我们在使用Java多线程时,一定需要考虑到共享,线程安全的相关内容。以下通过几个例子帮助大家来理解多线程时如何运行的,后续通过一篇文章详述解决办法:synchronized。
场景1:
第一次运行结果:
[当前线程]----------one=====实例变量的值----x=1
[当前线程]----------two=====实例变量的值----x=2
[当前线程]----------two=====实例变量的值----x=3
[当前线程]----------two=====实例变量的值----x=4
[当前线程]----------two=====实例变量的值----x=5
[当前线程]----------two=====实例变量的值----x=6
[当前线程]----------one=====实例变量的值----x=7
[当前线程]----------one=====实例变量的值----x=8
[当前线程]----------one=====实例变量的值----x=9
[当前线程]----------one=====实例变量的值----x=10
分析总结:我们在这里看到运行结果从1-10,线程th1和线程th2各自增加,此时两个线程公用一个对象B,所以也就共用x变量。且运行的是run函数里面的程序。
场景2:解决X变量被共用问题:
方法1:将int x=0;放入到run()函数中,此时,每个线程,都是从x=0开始执行;
方法2:创建多个B类的实例,比如b,b1,各自创建对应的线程进行处理,此时,两个线程互不干涉,代码如下
运行结果如下:
[当前线程]----------two=====实例变量的值----x=1
[当前线程]----------one=====实例变量的值----x=1
[当前线程]----------one=====实例变量的值----x=2
[当前线程]----------one=====实例变量的值----x=3
[当前线程]----------two=====实例变量的值----x=2
[当前线程]----------one=====实例变量的值----x=4
[当前线程]----------one=====实例变量的值----x=5
[当前线程]----------two=====实例变量的值----x=3
[当前线程]----------two=====实例变量的值----x=4
[当前线程]----------two=====实例变量的值----x=5
场景3:我们计划共同使用X,但是线程之间的运行需要先得到的运行结束后,后续的进程才能获得使用权,此时我们需要使用synchronized关键字来处理了代码如下。
运行结果如下
[当前线程]----------one=====实例变量的值----x=1
[当前线程]----------one=====实例变量的值----x=2
[当前线程]----------one=====实例变量的值----x=3
[当前线程]----------one=====实例变量的值----x=4
[当前线程]----------one=====实例变量的值----x=5
[当前线程]----------two=====实例变量的值----x=6
[当前线程]----------two=====实例变量的值----x=7
[当前线程]----------two=====实例变量的值----x=8
[当前线程]----------two=====实例变量的值----x=9
[当前线程]----------two=====实例变量的值----x=10
分析总结:我们在这里看到运行结果从1-10,但是运行过程中,是线程th1结束后,再开始th2。因为加了synchronzied,实现了同步,并且该对象锁对应的对象只有一个,那就是b,所以当第一个线程锁住了b,而第二个线程里面也是通过b去访问run()方法,所以必须等第一个线程执行完对象的方法时才能获得对象锁。
下一篇文章我们详细分析synchronized(同步)的概念。
先来一个总结:
1. java中的每个对象都有一个锁,当访问某个对象的synchronized方法时,表示将该对象上锁,此时其他任何线程都无法在去访问该syncronized 方法了,直到之前的那个线程执行方法完毕后,其他线程才有可能去访问该synchronized方法。
2.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
3.如果synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchuronized方法所在对象的对应的Class对象,
因为java中无论一个类有多少个对象,这些对象会对应唯一一个Class 对象,因此当线程分别访问同一个类的两个对象的static,synchronized方法时,他们的执行也是按顺序来的,也就是说一个线程先执行,一个线程后执行。