对java synchronized方法的深入理解
2015-05-03 22:38
851 查看
1. 首先加锁的是对象,而非代码。
在上述代码中,虽然同步了test方法,但是由于创建了两个不同的对象,所以ta.start线程开始运行的时候只是对对象ta进行了加锁。同理tb.start时候,只是对对象tb进行了加锁。所以两个线程之间不会相互影响。两个线程的test方法能够同时执行。
上述代码中同步了test方法,但是在类T3中访问的都是同一个对象 ta的test方法,所以十个线程都是顺序执行的。
2. 其他线程可以在被加锁的线程执行时访问同一个对象没有被加锁的方法。
输出结果:
updateA方法开始执行...
新线程updateB方法被执行...
a的当前的值:600
updateA方法执行完毕...
原因:首先方法updateA()被执行,此时对象t5被加锁,但是它的没有被加锁的方法updateB()仍然在updateA()执行的过程中可以执行。所以输出结果a的当前值为600而非0。
3. 由于加锁的是对象,所以当多个方法都加锁时,同一个时间段内,只能访问同一个对象的一个加锁方法.
输出结果为:
加锁方法被执行...
a的值:1000
方法upateA执行完成之后的时间为:5000
方法upateB开始执行的时间为:5000
updateB对象执行...
在updateB方法执行时,a的值:1000
方法updateA()和方法updateB()都被加锁,由于调用两个方法的对象是同一个t.当updateA访问时t被加锁,updateB()不能执行。所以才出现上面结果。updateA()完全执行完毕后,释放对象锁t,updateB()才能执行。
package lei.com.Sychronized; public class T2 extends Thread{ private String name; public T2(String name) { this.name=name; } private synchronized void test() { while(true) { System.out.println(name+"执行中...."); } } @Override public void run() { this.test(); } public static void main(String[] args) { T2 ta=new T2("ta"); T2 tb=new T2("tb"); ta.start(); tb.start(); } }
在上述代码中,虽然同步了test方法,但是由于创建了两个不同的对象,所以ta.start线程开始运行的时候只是对对象ta进行了加锁。同理tb.start时候,只是对对象tb进行了加锁。所以两个线程之间不会相互影响。两个线程的test方法能够同时执行。
package lei.com.Sychronized; public class T4 extends Thread{ private String name; private static int count=0; public T4(String name) { this.name=name; } public synchronized void test() { this.count++; System.out.println("线程"+count+"开始执行...."); try { this.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("线程"+count+"执行结束...."); } @Override public void run() { this.test(); } public static void main(String[] args) { T4 ta=new T4("ta"); for(int i=0;i<10;i++) { (new T3(ta)).start(); } package lei.com.Sychronized; public class T3 extends Thread { private T4 t4; public T3(T4 t4) { this.t4=t4; } @Override public void run() { t4.test(); } } } }
上述代码中同步了test方法,但是在类T3中访问的都是同一个对象 ta的test方法,所以十个线程都是顺序执行的。
2. 其他线程可以在被加锁的线程执行时访问同一个对象没有被加锁的方法。
package lei.com.Sychronized; public class T5 implements Runnable { private int a=0; private long startTime; public T5() { this.startTime=System.currentTimeMillis(); } public synchronized void updateA() { System.out.println("updateA方法开始执行..."); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("a的当前的值:"+a); a=800; System.out.println("updateA方法执行完毕..."); } public void run() { this.updateA(); } public void updateB() { a=600; System.out.println("新线程updateB方法被执行..."); } public static void main(String[] args) { T5 t5=new T5(); new Thread(t5).start(); try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t5.updateB(); } }
输出结果:
updateA方法开始执行...
新线程updateB方法被执行...
a的当前的值:600
updateA方法执行完毕...
原因:首先方法updateA()被执行,此时对象t5被加锁,但是它的没有被加锁的方法updateB()仍然在updateA()执行的过程中可以执行。所以输出结果a的当前值为600而非0。
3. 由于加锁的是对象,所以当多个方法都加锁时,同一个时间段内,只能访问同一个对象的一个加锁方法.
package lei.com.Sychronized; public class T implements Runnable { private int a=0; private long startTime; public T() { this.startTime=System.currentTimeMillis(); } public synchronized void updateA() { a=1000; System.out.println("加锁方法被执行..."); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("a的值:"+a); long currentTime=System.currentTimeMillis(); System.out.println("方法upateA执行完成之后的时间为:"+(currentTime-this.startTime)); } public void run() { this.updateA(); } public synchronized void updateB() { long currentTime=System.currentTimeMillis(); System.out.println("方法upateB开始执行的时间为:"+(currentTime-this.startTime)); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("updateB对象执行..."); System.out.println("在updateB方法执行时,a的值:"+a); a=200; } public static void main(String[] args) { T t=new T(); new Thread(t).start(); try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t.updateB(); } }
输出结果为:
加锁方法被执行...
a的值:1000
方法upateA执行完成之后的时间为:5000
方法upateB开始执行的时间为:5000
updateB对象执行...
在updateB方法执行时,a的值:1000
方法updateA()和方法updateB()都被加锁,由于调用两个方法的对象是同一个t.当updateA访问时t被加锁,updateB()不能执行。所以才出现上面结果。updateA()完全执行完毕后,释放对象锁t,updateB()才能执行。
相关文章推荐
- 深入理解Java中的同步静态方法和synchronized(class)代码块的类锁
- 深入理解java中的“==”与equals()方法
- 关于对java中synchronized修饰同一个类的两个方法的理解
- 深入理解synchronized方法同步的是方法还是对象?
- 深入理解Java中的synchronized锁重入
- 深入理解使用synchronized同步方法和同步代码块的区别
- 深入理解Java并发synchronized同步化的代码块不是this对象时的操作
- Java中关于Arrays.asList方法的深入学习与理解
- 深入理解Java并发4——synchronized关键字
- 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
- javaAPI深入理解(1)如何截短一个List以及List.subList()方法的坑
- 深入理解 Java 反射:Method (成员方法)
- 深入理解 Java 反射:Method (成员方法)
- 深入理解Java中HashCode方法
- java中synchronize关键字的理解 在多线程环境下的应用: synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。 1. syn
- 深入理解Java的方法重载机制
- Java Reflection深入理解方法(Method)
- Java Reflection深入理解私有变量和私有方法
- 深入理解Java并发之synchronized实现原理
- Java深入理解类、变量、方法的声明