Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 5412|回复: 0

[Java基础]多线程之并发性以及解决方法

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-16 10:04:15 | 显示全部楼层 |阅读模式

    首先演示一下并发性(关于并发性的解释建议看MSDN中.net部分相关的解释、感觉微软解释的很详细、不仅说了并发性 还有其他可能由多线程引发其他问题)

     1 public class ThreadDemo2 {
    2 public static void main(String[] args) {
    3 TestThread1 thread = new TestThread1();
    4 Thread t1 = new Thread(thread);
    5 Thread t2 = new Thread(thread);
    6
    7 t1.start();
    8 t2.start();
    9 }
    10 }
    11
    12 class TestThread1 implements Runnable {
    13 private int i = 0;
    14
    15 @Override
    16 public void run() {
    17 while (i < 50) {
    18 try {
    19 Thread.sleep(500); // 模拟CPU切换线程
    20 } catch (InterruptedException e) {
    21 e.printStackTrace();
    22 }
    23 System.out.println(i++);
    24 }
    25 }
    26 }

    上面的代码 在命令行只会输出50个数字、而不是和我们预期一样的 两个线程各输出50个数字、此时将线程类改成下面的形式

     1 class TestThread1 implements Runnable {
    2 // private int i = 0;
    3
    4 @Override
    5 public void run() {
    6 int i = 0;
    7 while (i < 50) {
    8 try {
    9 Thread.sleep(500); // 模拟CPU切换线程
    10 } catch (InterruptedException e) {
    11 e.printStackTrace();
    12 }
    13 System.out.println(i++);
    14 }
    15 }
    16 }

    就会和一开始预期的一样出现100个数字、当然出现数字是不具有确定性的、

     

    此时再举一个例子——单例模式、如下:

     1 class Singleton {
    2 private static Singleton obj;
    3
    4 private Singleton() {
    5 }
    6
    7 public static Singleton getInstance() {
    8 if (obj == null)
    9 obj = new Singleton();
    10 return obj;
    11 }
    12 }



    单例模式本意是希望只生成一个类的实例对象、但是很遗憾、单例模式这样的写法、并不是线程安全、也就是说在多线程的环境下有可能会产生一个以上的实例对象、具体代码如下:

     1 public class ThreadDemo3 {
    2 public static void main(String[] args) {
    3 TestThread2 t1 = new TestThread2();
    4 TestThread2 t2 = new TestThread2();
    5 TestThread2 t3 = new TestThread2();
    6
    7 t1.start();
    8 t2.start();
    9 t3.start();
    10
    11 /*
    12 * 我这的输出结果如下、
    13 * Singleton@3ce53108
    14 * Singleton@6af62373
    15 * Singleton@6af62373
    16 */
    17 }
    18 }
    19
    20 class Singleton {
    21 private static Singleton obj;
    22
    23 private Singleton() {
    24 }
    25
    26 public static Singleton getInstance() {
    27 if (obj == null)
    28 obj = new Singleton();
    29 return obj;
    30 }
    31 }
    32
    33 class TestThread2 extends Thread {
    34 @Override
    35 public void run() {
    36 System.out.println(Singleton.getInstance());
    37 }
    38 }


    在我的输出结果中、很显然t2/t3获得的是同一个对象(结果具有不确定性、你们的测试结果也许会出现三个对象相同、请多运行几次)、但是t1获得的是另一个对象、这显然就违背了单例模式的初衷、

    之所以会出现我们不希望的情况 是因为在第一个线程在判断了if(obj==null)之后 准备去构造对象(但是还没有构造)的时候、第二个线程调用了方法、并判断obj是否等于null、此时因为第一个线程还没有构造对象、所以第二个线程也进入了if语句块内、因此 出现了可能会构造两个不同的对象、

     

    在JDK1.5之前(不包括1.5)synchronized关键字来保证例子中单例模式的正确性、即这样定义单例模式

     1 class Singleton {
    2 private static Singleton obj;
    3
    4 private Singleton() {
    5 }
    6
    7 public synchronized static Singleton getInstance() {
    8 if (obj == null)
    9 obj = new Singleton();
    10 return obj;
    11 }
    12 }

     

    具体synchronized关键字的用途和说明可以参看JDK文档或者百度、我就不介绍了、(重点就搞清楚一个叫做锁(lock)或者叫监视器(Monitor)的东西即可)

     

    嗯 就记录这么多、下次自己应该能看懂、

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 14:12 , Processed in 1.017419 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表