美文网首页Java
一个例子讲Synchronized关键字

一个例子讲Synchronized关键字

作者: 小金狗子 | 来源:发表于2020-03-12 15:28 被阅读0次

引言

文中的例子从线程调度上讲不够严谨。原因是没输出,并不代表线程无法进入方法,有可能是线程一直没有被调度。

不过拿来讲Synchronized是可以的,因为两个有竞争线程,输出结果必然是先进入的线程输出完并且退出方法后,另一个才能输出

例子

public class SycTest {
  private Object ob = new Object();

  static synchronized void abc(String x){
    print(x);
  }
  synchronized void cde(String y){
    print(y);
  }

  synchronized void def(String y){
    print(y);
  }

  void fgh(String z){
    synchronized (ob){
      print(z);
    }
  }

  static void print(String c){
    for(int i=0;i<4 ;i++){
      System.out.print(c+",");
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
  public static void main(String[] args) throws InterruptedException {
    SycTest test = new SycTest();
    Thread t1 = new Thread(()->{test.cde("t1");});
    Thread t2 = new Thread(()->{test.def("t2");});
    Thread t3 = new Thread(()->{abc("t3");});
    Thread t4 = new Thread(()->{test.cde("t4");});
    Thread t5 = new Thread(()->{test.fgh("t5");});
   
    List<Thread> threads = new ArrayList<>(5);
    threads.add(t1);
    threads.add(t2);
    threads.add(t3);
    threads.add(t4);
    threads.add(t5);
    threads.parallelStream().forEach(t->t.start());
  }
}

跑几次后,代码输出结果

t3,t2,t5,t3,t2,t5,t3,t2,t5,t3,t5,t2,t1,t1,t1,t1,t4,t4,t4,t4,
t3,t5,t4,t3,t4,t5,t3,t5,t4,t3,t5,t4,t1,t1,t1,t1,t2,t2,t2,t2,
t3,t2,t5,t5,t2,t3,t2,t5,t3,t2,t5,t3,t4,t4,t4,t4,t1,t1,t1,t1,
t3,t1,t5,t3,t1,t5,t3,t1,t5,t3,t1,t5,t4,t4,t4,t4,t2,t2,t2,t2,

我们可以看到
t1的4次输出后t4才有机会输出或者相反。(同一个synchronized方法一次只能由一个线程执行)

t1(4)的4次输出后t2才有机会输出或者相反。(同一个实例的synchronized方法一次只能由一个线程执行)

t3的能够及时输出,没有一定的先后顺序。(synchronized修饰的static方法和实例方法可以同时执行,并不冲突。)

t5的能够及时输出,没有一定的先后顺序。(why)

解释

上面4点的解释,也算是java基础之一
1.synchronized修饰的实例方法是对当前对象实例加锁。
2.基于第1点,同一对象实例的不同synchronized方法不能同时执行,所以现实中应做好考虑。
3.synchronized修饰的static方法其实锁定的当前对象的Class对象,而Class对象只有一个。
4.synchronized块中,明确指定了synchronized的锁定的对象,就可能不会受第1点描述的影响。如果synchronized(this)的话就相当于第1点。
5.基于第3点,一个类中的两个synchronized修饰的static方法不能同时执行。

引申

关于synchronized(this)和第5点自行写例子验证。
想深入synchronized在JVM层面上的实现可以参考"死磕Synchronized底层实现" 概论链接https://juejin.im/post/5bfe6ddee51d45491b0163eb

相关文章

网友评论

    本文标题:一个例子讲Synchronized关键字

    本文链接:https://www.haomeiwen.com/subject/nmlpjhtx.html