synchronized锁住的对象问题

    xiaoxiao2021-04-15  69

    示例1:

    package com.线程间通信; public class MutiThread1 { private int a = 0; public synchronized void print(String tag){ try { if(tag.equals("a") ){ a = 100; System.out.println("tag a, set number over"); Thread.sleep(1000); }else{ a = 200; System.out.println("tag b set number over"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("tag "+tag+",a="+a); } public static void main(String[] args) { final MutiThread1 m1 = new MutiThread1(); final MutiThread1 m2 = new MutiThread1(); Thread t1 = new Thread(new Runnable() { public void run() { m1.print("a"); } }); Thread t2 = new Thread(new Runnable() { public void run() { m2.print("b"); } }); t1.start(); t2.start(); } }

    这段代码运行出来的结果为:

    tag a, set number over tag b set number over tag b,a=200 tag a,a=100 解释:m1和m2是两个不同的对象。m1对象调用print方法,synchronized锁住的对象为m1。而m2对象调用print方法,synchronized锁住的对象为m2。

    所以synchronized关键字没有实现锁住同一对象,也就达不到锁的目的了。

    示例2:

    package com.线程间通信; public class MutiThread1 {     private static int a = 0;          public static synchronized void  print(String tag){         try {             if(tag.equals("a") ){                 a = 100;                 System.out.println("tag a, set number over");                 Thread.sleep(1000);             }else{                 a = 200;                 System.out.println("tag b set number over");             }                      } catch (InterruptedException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }         System.out.println("tag "+tag+",a="+a);     }          public static void main(String[] args) {                  final MutiThread1 m1 = new MutiThread1();         final MutiThread1 m2 = new MutiThread1();                  Thread t1 = new Thread(new Runnable() {                          public void run() {                 m1.print("a");             }         });         Thread t2 = new Thread(new Runnable() {                          public void run() {                 m2.print("b");             }         });                  t1.start();         t2.start();     } } 示例2运行的结果为:

    tag a, set number over tag a,a=100 tag b set number over tag b,a=200

    解释:示例2代码中,在print方法的前面加上了static关键字,随之变量a也要加上static,这时的print方法是属于MutiThread1对象的。

    所以m1调用print方法时,synchronized关键字锁住的对象为MutiThread1。而m2对象调用print方法时,synchronized关键字锁住的对象也为MutiThread1。

    这样synchronized锁住的是同一个对象。实现了锁同步。

    总结:

    关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当做锁,所以示例代码中哪个线程先执行synchronized关键字的方法,哪个线程就持有

    该方法所属对象的锁(lock),两个对象,线程就是获得的两个不同的锁,他们之间互不影响。

    有一种情况是获得相同的锁,即在静态方法上加上synchronized关键字,表示锁定的是.class类,类一级别的锁(独占.class类)

    转载请注明原文地址: https://ju.6miu.com/read-670946.html

    最新回复(0)