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

首先演示一下并发性(关于并发性的解释建议看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@3ce5310814 * Singleton@6af6237315 * Singleton@6af6237316 */

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)的东西即可)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值