前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个例子讲Synchronized关键字

一个例子讲Synchronized关键字

原创
作者头像
小金狗子
修改2020-03-23 14:40:02
4220
修改2020-03-23 14:40:02
举报
文章被收录于专栏:用户7113604的专栏

引言

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

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

例子

代码语言:txt
复制
   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());

     }

   }

跑几次后,代码输出结果

代码语言:txt
复制
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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 例子
  • 解释
  • 引申
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档