Java多线程理解(线程安全)
2014-11-11 15:08
190 查看
我们在使用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方法时,他们的执行也是按顺序来的,也就是说一个线程先执行,一个线程后执行。
场景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方法时,他们的执行也是按顺序来的,也就是说一个线程先执行,一个线程后执行。
相关文章推荐
- Java多线程理解:线程安全的集合对象
- Java多线程理解:线程安全的集合对象
- Java 多线程编程之五:一个理解 wait() 与 notify() 的例子
- java多线程编程理解
- 关于Java中多线程的原理与本人的理解
- Java多线程(一)、理解进程与多线程的概念及关系
- java 中多线程的理解
- java多线程的理解
- Java中线程安全问题个人理解
- 从JAVA多线程理解到集群分布式和网络设计的浅析
- Java多线程编程--(3)线程互斥、同步的理解
- 线程进程Java多线程(一)、理解进程与多线程的概念及关系
- 从JAVA多线程理解到集群分布式和网络设计的浅析
- Java多线程 -- 深入理解JMM(Java内存模型) --(五)锁
- Java多线程 -- 深入理解JMM(Java内存模型) --(四)volatile
- 从JAVA多线程理解到集群分布式和网络设计的浅析
- java 多线程 Synchronized方法和方法块 synchronized(this)和synchronized(object)的理解
- Java多线程 -- 深入理解JMM(Java内存模型) --(三)顺序一致性
- Java多线程 -- 深入理解JMM(Java内存模型) --(六)final
- 从JAVA多线程理解到集群分布式和网络设计的浅析