【java】Synchronize关键字
来源:互联网 发布:魏晨全球歌迷会淘宝网 编辑:程序博客网 时间:2024/05/17 23:25
package Synchronize;/** * 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。 * 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块 * */public class Test01 implements Runnable { public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " synchronized loop:: " + i); }//这个部分可能是A0 B0等间隔出现 synchronized(this){//对象锁 一个时间段里面只有一个对象实例才能访问 且必须要等其执行完代码块 for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " synchronized loop " + i); } }//但是这个部分输出都是连续的 } public static void main(String[] args) { Test01 t1 = new Test01(); Thread ta = new Thread(t1, "A"); Thread tb = new Thread(t1, "B"); ta.start(); //不一定就一定是先输出A tb.start(); }}/*A synchronized loop:: 0B synchronized loop:: 0A synchronized loop:: 1B synchronized loop:: 1A synchronized loop:: 2B synchronized loop:: 2A synchronized loop:: 3A synchronized loop:: 4A synchronized loop 0A synchronized loop 1A synchronized loop 2A synchronized loop 3A synchronized loop 4B synchronized loop:: 3B synchronized loop:: 4B synchronized loop 0B synchronized loop 1B synchronized loop 2B synchronized loop 3B synchronized loop 4* */
package Synchronize;/** * 一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块 * */public class Test02 { public void m4t1() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public void m4t2() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " :: " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { Test02 myt2 = new Test02(); Thread t1 = new Thread( new Runnable() { public void run() { myt2.m4t1(); myt2.m4t2(); } }, "t1" ); Thread t2 = new Thread( new Runnable() { public void run() { myt2.m4t1();myt2.m4t2(); } }, "t2" ); //刚开始的时候 两个线程都想访问m4t1 但是只能有一个去访问 当t1线程去访问非同步方法的时候,t2就去访问其同步方法 t1.start(); t2.start(); }}
package Synchronize;/** * 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问是阻塞的 * */public class Test03 { public void m4t1() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public void m4t2() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public void m4t3() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public static void main(String[] args) { Test03 myt2 = new Test03(); Thread t1 = new Thread( new Runnable() { public void run() { myt2.m4t1(); } }, "t1" ); Thread t2 = new Thread( new Runnable() { public void run() { myt2.m4t2(); } }, "t2" ); Thread t3 = new Thread( new Runnable() { public void run() { myt2.m4t3(); } }, "t3" ); t1.start(); t2.start(); t3.start(); }}/*t2 : 4t2 : 3t2 : 2t2 : 1t2 : 0t3 : 4t3 : 3t3 : 2t3 : 1t3 : 0t1 : 4t1 : 3t1 : 2t1 : 1t1 : 0* */
package Synchronize;/** * 当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。 * 结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞 * */public class Test04 { public void m4t1() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public synchronized void m4t2() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { Test04 myt4 = new Test04(); Thread t1 = new Thread( new Runnable() { public void run() { myt4.m4t1(); } }, "t1" ); Thread t2 = new Thread( new Runnable() { public void run() { myt4.m4t2(); } }, "t2" ); t1.start(); t2.start(); }}
package Synchronize;public class Test05 { class Inner { private void m4t1() { int i = 5; while(i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i); try { Thread.sleep(500); } catch(InterruptedException ie) { } } } private void m4t2() { int i = 5; while(i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); try { Thread.sleep(500); } catch(InterruptedException ie) { } } } } private void m4t1(Inner inner) { synchronized(inner) { //使用对象锁 inner.m4t1(); } } private void m4t2(Inner inner) { inner.m4t2(); } public static void main(String[] args) { final Test05 myt3 = new Test05(); final Inner inner = myt3.new Inner();//普通内部类 Thread t1 = new Thread( new Runnable() {public void run() { myt3.m4t1(inner);} }, "t1"); Thread t2 = new Thread( new Runnable() {public void run() { myt3.m4t2(inner);} }, "t2"); t1.start(); t2.start(); }}/*尽管线程t1获得了对Inner的对象锁,但由于线程t2访问的是同一个Inner中的非同步部分。所以两个线程互不干扰。t2 : Inner.m4t2()=4t1 : Inner.m4t1()=4t1 : Inner.m4t1()=3t2 : Inner.m4t2()=3t2 : Inner.m4t2()=2t1 : Inner.m4t1()=2t1 : Inner.m4t1()=1t2 : Inner.m4t2()=1t1 : Inner.m4t1()=0t2 : Inner.m4t2()=0* */
package Synchronize;public class Test06 { class Inner { private void m4t1() { int i = 5; while(i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i); try { Thread.sleep(500); } catch(InterruptedException ie) { } } } private synchronized void m4t2() { int i = 5; while(i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); try { Thread.sleep(500); } catch(InterruptedException ie) { } } } } private void m4t1(Inner inner) { synchronized(inner) { //使用对象锁 inner.m4t1(); } } private void m4t2(Inner inner) { inner.m4t2(); } public static void main(String[] args) { final Test06 myt3 = new Test06(); final Inner inner = myt3.new Inner();//普通内部类 Thread t1 = new Thread( new Runnable() {public void run() { myt3.m4t1(inner);} }, "t1"); Thread t2 = new Thread( new Runnable() {public void run() { myt3.m4t2(inner);} }, "t2"); t1.start(); t2.start(); }}/*加在内部类里面的方法t1 : Inner.m4t1()=4t1 : Inner.m4t1()=3t1 : Inner.m4t1()=2t1 : Inner.m4t1()=1t1 : Inner.m4t1()=0t2 : Inner.m4t2()=4t2 : Inner.m4t2()=3t2 : Inner.m4t2()=2t2 : Inner.m4t2()=1t2 : Inner.m4t2()=0* */
package Synchronize;public class Test07 { class Inner { private void m4t1() { int i = 5; while(i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i); try { Thread.sleep(500); } catch(InterruptedException ie) { } } } private void m4t2() { int i = 5; while(i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); try { Thread.sleep(500); } catch(InterruptedException ie) { } } } } private void m4t1(Inner inner) { synchronized(inner) { //使用对象锁 inner.m4t1(); } } private synchronized void m4t2(Inner inner) { inner.m4t2(); } public static void main(String[] args) { final Test07 myt3 = new Test07(); final Inner inner = myt3.new Inner();//普通内部类 Thread t1 = new Thread( new Runnable() {public void run() { myt3.m4t1(inner);} }, "t1"); Thread t2 = new Thread( new Runnable() {public void run() { myt3.m4t2(inner);} }, "t2"); t1.start(); t2.start(); }}/*按照Test04的理解是应该先输完某一个再输另外一个的 但是实际的结果交错的再结合Test06 其实调用方法的时候还是要去看其最底层是不是同步的加在内部类外面的方法t1 : Inner.m4t1()=4t2 : Inner.m4t2()=4t1 : Inner.m4t1()=3t2 : Inner.m4t2()=3t1 : Inner.m4t1()=2t2 : Inner.m4t2()=2t1 : Inner.m4t1()=1t2 : Inner.m4t2()=1t2 : Inner.m4t2()=0t1 : Inner.m4t1()=0* */
三句话:
第一,同步代码块或者同步方法体和非同步一起,两个线程可以一起访问非,但是只能先后顺序访问同
第二,访问一个同将导致其他同阻塞 但是不会阻塞非同
第三,是否真正同步需要看最底层(内部类)
但是需要注意的是上面都是不同线程 同一个对象,如果是不同的对象呢?
package Synchronize;public class Test031 { public void m4t1() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public void m4t2() { synchronized(this) { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public void m4t3() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { Test031 myt2 = new Test031(); Test031 myt3 = new Test031();//隶属于两个不同的对象锁,所以是可以交替进行的 前面我们所讲都是不同线程 同一个对象 Thread t1 = new Thread( new Runnable() { public void run() { myt2.m4t1(); } }, "t1" ); Thread t2 = new Thread( new Runnable() { public void run() { myt3.m4t1(); } }, "t2" ); t1.start(); t2.start(); }}/*t2 : 4t1 : 4t1 : 3t2 : 3t1 : 2t2 : 2t2 : 1t1 : 1t2 : 0t1 : 0* */
不同的实例对象拥有不同的锁,因此互不干扰
java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的
package Synchronize;/** * 类锁和对象锁是两个不一样的锁,控制着不同的区域,它们是互不干扰的。 * 同样,线程获得对象锁的同时,也可以获得该类锁,即同时获得两个锁,这是允许的。 */public class Test033 { public synchronized void test1() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static synchronized void test2() { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { final Test033 myt2 = new Test033(); Thread test1 = new Thread( new Runnable() { public void run() { myt2.test1(); } }, "test1" ); Thread test2 = new Thread( new Runnable() { public void run() { Test033.test2(); } }, "test2" ); test1.start(); test2.start(); }}/*test1 : 4test2 : 4test1 : 3test2 : 3test1 : 2test2 : 2test1 : 1test2 : 1test1 : 0test2 : 0* */
package Synchronize;/** * 类锁 同一时间内只有一个类实例可以获得 * */public class Test032 { public void test1() { synchronized(Test032.class)//类锁 { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public static synchronized void test2() //静态方法的类锁 { int i = 5; while( i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } public static void main(String[] args) { final Test032 myt2 = new Test032(); Thread test1 = new Thread( new Runnable() { public void run() { myt2.test1(); } }, "test1" ); Thread test2 = new Thread( new Runnable() { public void run() { Test032.test2(); } }, "test2" ); test1.start(); test2.start(); }}/*test1 : 4test1 : 3test1 : 2test1 : 1test1 : 0test2 : 4test2 : 3test2 : 2test2 : 1test2 : 0* */
参考文章:
http://langgufu.iteye.com/blog/2152608
http://www.importnew.com/20444.html
http://liuinsect.iteye.com/blog/1662839
1 0
- 【java】Synchronize关键字
- java修饰符:Synchronize关键字
- synchronize关键字
- java 修饰符(transient volatile Synchronize 关键字)
- Java多线程之深入理解synchronize关键字
- java多线程基础(synchronize关键字)
- java synchronize
- synchronize java
- java 修饰符的作用三(transient volatile Synchronize 关键字)
- Java并发编程-06-Synchronize关键字同步机制
- Android中的Synchronize关键字
- 线程安全 synchronize关键字
- synchronize 关键字用法
- synchronize关键字互斥
- 【java】线程同步关键字volatile,synchronize,取消串行化关键字transient
- 简化理解之:关键字synchronize
- Java synchronize 与 static synchronize 方式对比
- Java中的synchronize
- GreenDAO之「02.Eclipse环境下的基本操作」
- Perl操作excel2007的模块
- poj 1260 Pearls(DP)
- thinking in java——0327学习笔记
- MapReduce之去重计数类应用
- 【java】Synchronize关键字
- Java笔记之三
- 插件maven-compiler-plugin
- Linux多线程——使用信号量同步线程
- ArrayList、Vector、HashMap、HashSet的默认初始容量、加载因子、扩容增量
- 二叉树的前/中/后序遍历算法(非递归)
- 利用SQOOP将数据从数据库导入到HDFS
- swift系列:新手村第一周
- 【HTML】No.5 HTML属性