`

synchronized(this)理解

阅读更多

1、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

2、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问object中的非synchronized(this)同步代码块。

3、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其他synchronized(this)同步代码块得访问将被阻塞。

4、第三个例子同样适用其他同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其他线程对该object对象所有同步代码部分的访问都将被暂时阻塞。

5、以上规则对其他对象锁同样适用

 

一、

Java代码  收藏代码
  1. public class Thread1 implements Runnable{  
  2.   
  3.     /** 
  4.      * 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。 
  5.      * 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         Thread1 t1=new Thread1();  
  10.         Thread ta=new Thread(t1,"A");  
  11.         Thread tb=new Thread(t1,"B");  
  12.         ta.start();  
  13.         tb.start();  
  14.     }  
  15.   
  16.     @Override  
  17.     public void run() {  
  18.         synchronized(this){  
  19.             for(int i=0;i<5;i++){  
  20.                 System.out.println(Thread.currentThread().getName()+" synchronized loop "+i);  
  21.             }  
  22.         }  
  23.     }  
  24.   
  25. }  

 执行结果:

     A synchronized loop 0
     A synchronized loop 1
     A synchronized loop 2
     A synchronized loop 3
     A synchronized loop 4
     B synchronized loop 0
     B synchronized loop 1
     B synchronized loop 2
     B synchronized loop 3

     B synchronized loop 4

二、

Java代码  收藏代码
  1. package review.testSynchronized;  
  2.   
  3. public class Thread2 implements Runnable {  
  4.   
  5.     /** 
  6.      * 然而,当一个线程访问object的一个synchronized(this)同步代码块时, 
  7.      * 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。 
  8.      * @param args 
  9.      */  
  10.     public static void main(String[] args) {  
  11.         final Thread2 myt2=new Thread2();  
  12.         Thread t1=new Thread(  
  13.         new Runnable(){  
  14.             public void run(){  
  15.                 myt2.m4t1();  
  16.             }  
  17.         },"t1"  
  18.         );  
  19.         Thread t2=new Thread(  
  20.                 new Runnable(){  
  21.                     public void run(){  
  22.                         myt2.m4t2();  
  23.                     }  
  24.                 },"t2"  
  25.                 );  
  26.         t1.start();  
  27.         t2.start();  
  28.     }  
  29.     public void m4t1(){  
  30.         synchronized(this){  
  31.             int i=5;  
  32.             while(i-->0){  
  33.                 System.out.println(Thread.currentThread().getName()+" : "+i);  
  34.             }  
  35.             try {  
  36.                 Thread.sleep(500);  
  37.             } catch (InterruptedException e) {  
  38.                 e.printStackTrace();  
  39.             }  
  40.         }  
  41.     }  
  42.     public void m4t2(){  
  43.         int i=5;  
  44.         while(i-->0){  
  45.             System.out.println(Thread.currentThread().getName()+" : "+i);  
  46.         }  
  47.         try {  
  48.             Thread.sleep(500);  
  49.         } catch (InterruptedException e) {  
  50.             e.printStackTrace();  
  51.         }  
  52.     }  
  53.     @Override  
  54.     public void run() {  
  55.           
  56.     }  
  57.   
  58. }  

 

 执行结果:

     t1 : 4
     t1 : 3
     t1 : 2
     t1 : 1
     t2 : 4
     t2 : 3
     t2 : 2
     t2 : 1
     t2 : 0
     t1 : 0


 

三、

Java代码  收藏代码
  1. package review.testSynchronized;  
  2.   
  3. public class Thread3 {  
  4.   
  5.     /** 
  6.      * 三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时, 
  7.      * 其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。 
  8.      * @param args 
  9.      */  
  10.     public static void main(String[] args) {  
  11.         final Thread3 myt2=new Thread3();  
  12.         Thread t1=new Thread(  
  13.         new Runnable(){  
  14.             public void run(){  
  15.                 myt2.m4t1();  
  16.             }  
  17.         },"Thread3_t1"  
  18.         );  
  19.         Thread t2=new Thread(  
  20.                 new Runnable(){  
  21.                     public void run(){  
  22.                         myt2.m4t2();  
  23.                     }  
  24.                 },"Thread3_t2"  
  25.                 );  
  26.         t1.start();  
  27.         t2.start();  
  28.     }  
  29.     public void m4t1(){  
  30.         synchronized(this){  
  31.             int i=5;  
  32.             while(i-->0){  
  33.                 System.out.println(Thread.currentThread().getName()+" : "+i);  
  34.             }  
  35.             try {  
  36.                 Thread.sleep(500);  
  37.             } catch (InterruptedException e) {  
  38.                 e.printStackTrace();  
  39.             }  
  40.         }  
  41.     }  
  42.     public void m4t2(){  
  43.         synchronized(this){  
  44.             int i=5;  
  45.             while(i-->0){  
  46.                 System.out.println(Thread.currentThread().getName()+" : "+i);  
  47.             }  
  48.             try {  
  49.                 Thread.sleep(500);  
  50.             } catch (InterruptedException e) {  
  51.                 e.printStackTrace();  
  52.             }  
  53.         }  
  54.           
  55.     }  
  56. }  

 执行结果:

 

     Thread3_t1 : 4
     Thread3_t1 : 3
     Thread3_t1 : 2
     Thread3_t1 : 1
     Thread3_t1 : 0
     Thread3_t2 : 4
     Thread3_t2 : 3
     Thread3_t2 : 2
     Thread3_t2 : 1
     Thread3_t2 : 0 

 

四、

Java代码  收藏代码
  1. package review.testSynchronized;  
  2.   
  3. public class Thread4 {  
  4.   
  5.     /** 
  6.      * 四、第三个例子同样适用其它同步代码块。 
  7.      * 也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。 
  8.      * 结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。 
  9.      * @param args 
  10.      */  
  11.     public static void main(String[] args) {  
  12.         final Thread4 myt4=new Thread4();  
  13.         Thread t1=new Thread(  
  14.         new Runnable(){  
  15.             public void run(){  
  16.                 myt4.m4t1();  
  17.             }  
  18.         },"Thread4_t1"  
  19.         );  
  20.         Thread t2=new Thread(  
  21.                 new Runnable(){  
  22.                     public void run(){  
  23.                         myt4.m4t2();  
  24.                     }  
  25.                 },"Thread4_t2"  
  26.                 );  
  27.         t1.start();  
  28.         t2.start();  
  29.     }  
  30.     public void m4t1(){  
  31.         synchronized(this){  
  32.             int i=5;  
  33.             while(i-->0){  
  34.                 System.out.println(Thread.currentThread().getName()+" : "+i);  
  35.             }  
  36.             try {  
  37.                 Thread.sleep(500);  
  38.             } catch (InterruptedException e) {  
  39.                 e.printStackTrace();  
  40.             }  
  41.         }  
  42.     }  
  43.     public synchronized void m4t2(){  
  44.             int i=5;  
  45.             while(i-->0){  
  46.                 System.out.println(Thread.currentThread().getName()+" : "+i);  
  47.             }  
  48.             try {  
  49.                 Thread.sleep(500);  
  50.             } catch (InterruptedException e) {  
  51.                 e.printStackTrace();  
  52.             }  
  53.           
  54.     }  
  55. }  

 

执行结果:

     Thread4_t1 : 4
     Thread4_t1 : 3
     Thread4_t1 : 2
     Thread4_t1 : 1
     Thread4_t1 : 0
     Thread4_t2 : 4
     Thread4_t2 : 3
     Thread4_t2 : 2
     Thread4_t2 : 1
     Thread4_t2 : 0

 

 五、

Java代码  收藏代码
  1. package review.testSynchronized;  
Java代码  收藏代码
  1. public class Thread5 {  
Java代码  收藏代码
  1.  /** 
  2.   * @param args 
  3.   */  
  4.  public static void main(String[] args) {  
  5.   final Thread5 myt5=new Thread5();  
  6.   final Inner inner=myt5.new Inner();  
  7.   Thread t1=new Thread(new Runnable(){  
  8.    public void run(){  
  9.     myt5.m4t1(inner);  
  10.    }  
  11.   },"Thread5_t1"  
  12.      );  
  13.   Thread t2=new Thread(new Runnable(){  
  14.    public void run(){  
  15.     myt5.m4t2(inner);  
  16.    }  
  17.   },"Thread5_t2"  
  18.      );  
  19.   t1.start();  
  20.   t2.start();  
  21.  }  
  22.     class Inner{  
  23.      private void m4t1(){  
  24.       int i=5;  
  25.       while(i-->0){  
  26.        System.out.println(Thread.currentThread().getName()+":Inner.m4t1()="+i);  
  27.        try{  
  28.         Thread.sleep(500);  
  29.        }catch(Exception e){  
  30.           
  31.        }  
  32.       }  
  33.      }  
  34.      private void m4t2(){  
  35.          int i=5;  
  36.          while(i-->0){  
  37.           System.out.println(Thread.currentThread().getName()+":Inner.m4t2()="+i);  
  38.           try{  
  39.               Thread.sleep(500);  
  40.              }catch(Exception e){    
  41.              }  
  42.          }  
  43.         }  
  44.     }  
  45.     private void m4t1(Inner inner){  
  46.      synchronized(inner){//使用对象锁  
  47.      inner.m4t1();  
  48.      }  
  49.     }  
  50.     private void m4t2(Inner inner){  
  51.      inner.m4t2();  
  52.     }  
  53.       
  54. }  

 

执行结果:

(尽管t1获得了对Inner的对象锁,但由于线程t2 访问的是同一个inner的非同步部分。所所以两个线程互不干扰)

     Thread5_t1:Inner.m4t1()=4
     Thread5_t2:Inner.m4t2()=4
     Thread5_t2:Inner.m4t2()=3
     Thread5_t1:Inner.m4t1()=3
     Thread5_t2:Inner.m4t2()=2
     Thread5_t1:Inner.m4t1()=2
     Thread5_t2:Inner.m4t2()=1
     Thread5_t1:Inner.m4t1()=1
     Thread5_t1:Inner.m4t1()=0
     Thread5_t2:Inner.m4t2()=0

 

现在在Inner.m4t2()前面加上synchronized:

(尽管t1与t2访问了同一个对象中两个毫不相干的部分,但因为t1先获得了对对象Inner的对象锁,所以t2对Inner.m4t2()的访问也被阻塞,因为m4t2()是Inner中的一个同步方法)

     Thread5_t1:Inner.m4t1()=4
     Thread5_t1:Inner.m4t1()=3
     Thread5_t1:Inner.m4t1()=2
     Thread5_t1:Inner.m4t1()=1
     Thread5_t1:Inner.m4t1()=0
     Thread5_t2:Inner.m4t2()=4
     Thread5_t2:Inner.m4t2()=3
     Thread5_t2:Inner.m4t2()=2
     Thread5_t2:Inner.m4t2()=1
     Thread5_t2:Inner.m4t2()=0

 

分享到:
评论

相关推荐

    java的线程同步机制synchronized关键字的理解_.docx

    Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...

    实例解析Java中的synchronized关键字与线程平安问题_.docx

    但是,很多开发者对 synchronized 关键字的理解并不够深入,本文将通过实例解析 Java 中的 synchronized 关键字与线程平安问题,帮助开发者更好地理解和使用 synchronized 关键字。 首先,需要清晰的是 ...

    Java学习题答案

    相关知识可以自己参考相关资料加上自己的理解.欢迎拍砖 1.简述逻辑操作(&,|,^)与条件操作(&&,||)的区别。(15分) 区别主要答两点: a.条件操作只能操作布尔型的,而逻辑操作不仅可以操作布尔型,而且可以操作...

    达内 coreJava 习题答案

    else if (mark&gt;=80) System.out.println("this mark is grade \'B\' "); else if (mark&gt;=70) System.out.println("this mark is grade \'C\' "); else if (mark&gt;=60) System.out.println("this mark is grade \'D...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段21讲、通过实验分析This锁的存在.mp4 │ 高并发编程第一阶段22讲、通过实验分析Class锁的存在.mp4 │ 高并发编程第一阶段23讲、多线程死锁分析,案例介绍.mp4 │ 高并发编程第一阶段24讲、...

    sesvc.exe 阿萨德

    一文让你彻底理解 Java HashMap 和 ConcurrentHashMap 2018-07-25 分类:JAVA开发、编程开发、首页精华0人评论 来源:crossoverjie.top 分享到:更多0 前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常...

    java基础案例与开发详解案例源码全

    12.5.1 使用synchronized同步块324 12.5.2 使用集合工具类同步化集合类对象324 12.5.3 使用JDK5.0后提供的并发集合类324 12.6 用Timer类调度任务325 12.7 本章练习326 第13章 13.1 java.io.File类328 13.1.1 文件和...

    二十三种设计模式【PDF版】

    Most developers claim to experience an epiphany reading this book. If you've never read the Design Patterns book then you have suffered a very serious gap in your programming education that should be...

    java语言关键字.pdf

    本文将对Java语言关键字进行分类详解,帮助读者深入理解Java语言的基础知识。 访问控制关键字 * private:用在方法或变量的声明中,表示这个方法或变量只能被这个类的其它元素所访问。 * protected:用在方法和...

    大数据面试题.pdf

    public ArrayList() { this(10); } 默认的扩充是10由此计算 1-11)java的拆包与封包的问题 System.out.println("5" + 2); 52 1-12)Java中Class.forName和ClassLoader.loadClass的区别 Class.forName("xx.xx")等同...

    Java面试宝典2020修订版V1.0.1.doc

    3、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 56 4、线程的基本概念 57 5、什么是多线程 57 6、程序、进程、线程之间的关系 57 7、创建线程有几种方式,分别是什么? ...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    要了解面向对象编程(OOP)的基本概念,需要理解 OOP 的三个主要概念,它们撑起 了整个 OOP 的框架。这三个概念是:封装、继承性和多态性。除此以外,还需了解对象、 类、消息、接口、及抽象等概念。 2.2.1 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    7.8 this关键字:指向对象自己的引用 177 7.8.1 发现问题:当实例变量和局部变量重名 177 7.8.2 经常深藏不露的this关键字 178 7.8.3 在方法中调用方法 179 7.9 构造方法(Constructor) 181 7.9.1 构造...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    7.8 this关键字:指向对象自己的引用 177 7.8.1 发现问题:当实例变量和局部变量重名 177 7.8.2 经常深藏不露的this关键字 178 7.8.3 在方法中调用方法 179 7.9 构造方法(Constructor) 181 7.9.1 构造...

    net学习笔记及其他代码应用

    1. 简述 private、 protected、 public、 internal 修饰符的访问权限。 答 . private : 私有成员, 在类的内部才可以访问。...47.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可...

Global site tag (gtag.js) - Google Analytics