线程“八锁“ synchronized到底是对哪个对象加锁?
创始人
2024-02-21 09:27:46

线程"八锁" synchronized到底是对哪个对象加锁?

习题一

class Number{public synchronized void a(){System.out.println("1");}public synchronized void b(){System.out.println("2");}
}
public class TestBlock {public static void main(String[] args) throws InterruptedException {Number n = new Number();Thread t1 = new Thread(()->{System.out.println("t1->begin!!!");n.a();});Thread t2 = new Thread(()->{System.out.println("t2->begin!!!");n.b();});t1.start();t2.start();t1.join();t2.join();}
}

对于Number类里面的a方法和b方法都是对当前对象this加锁,也就是对Number对象加锁.

当两个线程通过对象调用两个方法(a和b)的时候,会产生互斥效果-->锁的都是同一个对象(Number对象)

对于打印结果取决于任务调度器先调度谁就先打印谁,两者都有机会被优先调度,所以打印顺序可能是 1 2 也可能是2 1.

习题二

class Number1{public synchronized void a(){System.out.println("1");}public synchronized void b(){System.out.println("2");}
}
public class TestBlock1 {public static void main(String[] args) throws InterruptedException {Number1 n = new Number1();Thread t1 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1->begin!!!");n.a();});Thread t2 = new Thread(()->{System.out.println("t2->begin!!!");n.b();});t1.start();t2.start();t1.join();t2.join();}
}

对比习题1就相当于在t1线程里面多加了个sleep,让其t1线程睡眠一会.

但是,t1线程和t2线程锁的还是同一个对象Number具有互斥效果.

打印结果还是取决于任务调度器的调度,如果先调度的是t1(t1先拿到锁),那么就等待1s后,执行a方法打印1,然后线程2在执行b方法,打印2.

还有一种情况是任务调度器先调度t2线程,就会先打印2,然后睡眠1s后打印1.

习题3

class Number3{public synchronized void a(){System.out.println("1");}public synchronized void b(){System.out.println("2");}public void c(){//没有加锁System.out.println("3");}
}
public class TestBlock3 {public static void main(String[] args) throws InterruptedException {Number3 n = new Number3();Thread t1 = new Thread(()->{try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1->begin!!!");n.a();});Thread t2 = new Thread(()->{System.out.println("t2->begin!!!");n.b();});Thread t3 = new Thread(()->{System.out.println("t3->begin!!!");n.c();});t1.start();t2.start();t3.start();t1.join();t2.join(); t3.join();}
}

习题3是多加了一个方法c,但是方法c没有加synchronized.

对于这个题,方法a,b都加了synchronized可以其互斥效果,但是反方c没有加synchronized,不会被加锁.也就是线程1或者线程2执行,线程3不会阻塞,依然会继续往后执行.

对于打印结果还是取决于任务调度器的调度.

如果先调度的是线程1,那么会等待1s后打印1,但是方法c没有加锁,所以不会阻塞,线程3执行方法c打印3,然后1s后打印1 ,线程1释放锁之后唤醒线程2,线程2执行b方法打印2.====> 3 一秒后 1 2

由于线程2和线程3是并发执行的取决于任务调度器

如果先调度的是线程2,那么会先打印 2 ,然后线程3并发/并行的执行方法c打印3,然后一秒后打印1

===> 2 3 一秒后 1

如果先调度的是线程3,那么会先打印 3 ,然后线程2并发/并行的执行方法b打印2,然后一秒后打印1

===> 3 2 一秒后 1

习题4

class Number4{public synchronized void a(){System.out.println("1");}public synchronized void b(){System.out.println("2");}
}
public class TestBlock4 {public static void main(String[] args) throws InterruptedException {Number4 n1 = new Number4();Number4 n2 = new Number4();Thread t1 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1->begin!!!");n1.a();});Thread t2 = new Thread(()->{System.out.println("t2->begin!!!");n2.b();});t1.start();t2.start();t1.join();t2.join();}
}

这个题有两个对象n1和n2.

有两个对象,n1.a(),n2.b(),既然是不同的对象,也就是线程1和线程2对不同的对象加锁=>锁的不是同一个对象不产生互斥效果,并发/并行的执行,但由于t1线程睡眠1s钟,所以总是先打印2 一秒后 在打印1

习题5

class Number5{public synchronized static void a(){System.out.println("1");}public synchronized void b(){System.out.println("2");}
}
public class TestBlock5 {public static void main(String[] args) throws InterruptedException {Number5 n = new Number5();Thread t1 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1->begin!!!");n.a();});Thread t2 = new Thread(()->{System.out.println("t2->begin!!!");n.b();});t1.start();t2.start();t1.join();t2.join();}
}

线程1调用a方法,a是静态方法,对静态方法加锁相当于是对类对象加锁-->锁的是Number类对象

线程2调用b方法,b是非静态方法,相当于对this对象加锁->也就是n对象

所以锁的是不同的对象==>对不同的对象进行加锁--->不会产生互斥效果

所以两线程是并发执行的,由于睡眠,先打印2,一秒后打印1

习题6

class Number6 {public synchronized static void a(){System.out.println("1");}public synchronized static void b(){System.out.println("2");}
}
public class TestBlock6 {public static void main(String[] args) throws InterruptedException {Number6 n = new Number6();Thread t1 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t1->begin!!!");n.a();});Thread t2 = new Thread(()->{System.out.println("t2->begin!!!");n.b();});t1.start();t2.start();t1.join();t2.join();}
}

两个线程调用的方法都是对静态方法进行加锁==>都是对类对象加锁-->锁的是相同对象-->产生互斥效果.

取决于任务调度器. 先调度线程1就是 1s之后打印1 ,然后打印2,否则的话先调度线程2就是 打印2 ,1s之后然后打印1

习题7

class Number7 {public synchronized static void a(){System.out.println("1");}public synchronized  void b(){System.out.println("2");}
}
public class TestBlock7 {public static void main(String[] args) {Number7 n1 = new Number7();Number7 n2 = new Number7();Thread t1 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}n1.a();});Thread t2 = new Thread(()->{n2.b();});t1.start();t2.start();}
}

加锁的对象不一样,线程1调用的方法对类对象加锁,线程2里面利用n2对象调用b方法,对n2对象加锁,所以两个线程是对不同的对象进行加锁->不产生互斥效果.

所以线程1和线程2是并发执行的,所以是先打印2,一秒后打印1

习题8

class Number8{public static synchronized void a() {System.out.println("1");}public static synchronized void b() {System.out.println("2");}
}
public class TestBlock8 {public static void main(String[] args) {Number8 n1 = new Number8();Number8 n2 = new Number8();Thread t1 = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}n1.a();});Thread t2 = new Thread(()->{n2.b();});t1.start();t2.start();}
}

虽然是不同的对象调用方法

但是调用的方法都是对静态方法进行加锁==>都是对类对象加锁-->锁的是相同对象-->产生互斥效果.

取决于任务调度器. 先调度线程1就是 1s之后打印1 ,然后打印2,否则的话先调度线程2就是 打印2 ,1s之后然后打印1

总结

分析这种问题,首先往最根头看起,到底锁的对象是谁,是this还是类对象,还是没有加锁,然后在确定多个对象是否是锁的同一个对象

  • 如果锁的是同一个对象,那么会产生互斥效果,一个线程没有执行完,另外一个线程阻塞等待.
  • 锁的不是同一个对象,那么就不会产生互斥效果,并行的执行
  • 如果没有加锁,那么也是会与其他线程并行的执行

然后具体情况具体分析,可能分为多种情况-->这种情况就要考虑任务调度器的调度执行了.--->分多种情况去考虑即可

参考 :

黑马程序员JUC视频-->哔哩哔哩

相关内容

热门资讯

【看表情包学Linux】进程地...   🤣 爆笑教程 👉 《看表情包学Linux》👈 猛...
吉字五行及吉凶 吉字五行中代表... 五行解析在文化中,五行是非常重要的概念之一,在这里解析一下五行对于人们生活的影响。首先,金属代表的是...
月老姻缘灵签内容详解大全 月老... 月老灵签 姻缘签44签 求解签君尔目下之人。本是可心满意足之人。焉知后来之人。一个比一个更美好。就此...
六爻排盘蛇 六爻排盘预测绝招 ... 六爻排盘结果怎么看纳甲六爻在线排盘姓名:出生年:1981性别:男占事:起卦方式:手动摇卦公历时间:2...
吉凶由情绪决定 每日吉凶 每月... 情绪的力量情绪是我们生活中一个重要的组成部分。我们每天都会通过不同的方式感受到情绪的存在,而情绪的质...
吉凶悔吝的解释是什么 风水形势... 吉凶悔吝的解释是什么从古至今,人们对于吉凶悔吝都有着不同的看法。所谓吉,是指好的运气,让人们沾沾自喜...
如何看每日生肖运势 每日生肖运... 背景说明每个人都希望自己的运势越来越好,而对于人来说,生肖运势是一个参考价值很高的判断标准。按照传统...
最准观音灵签21签解签 观音灵... 观音灵签21签解签-遵医嘱,健康长寿观音精神签证是中国民间宗教信仰的重要形式,也是一种广泛流传的祈祷...
梦见红裤子被水冲走 梦见河里洗... 梦见红裤子被水冲走红裤子是一种比较鲜艳的颜色,在梦中出现可能代表着某种情绪或状态。而被水冲走则更加具...
十二星座对象配对 12星座最佳... 12星座配偶标准白羊座:温柔善良的人乐观单纯的白羊座在恋爱时喜欢另一半无条件的宠爱自己,另一半对自己...
带水又带土的名字女孩名字有哪些... 含水和土的字有哪些含水的字:淦、澜、浸、泼、滴、没、汪、沸、鸿、沔、浩、渣、溢、潺江、注、漭、淬、澧...
六爻失物卦 在线占卜失物 六爻... 六爻占卜 寻找失物公历起卦时间:2012年12月24日9时44分(按公历时间起卦)农历:仁辰年十一月...
天网今日生肖运势 每日特吉生肖... 天网今日生肖运势天网今日,十二生肖依旧是重要的关键词之一。根据传统文化和民间信仰,每个人都属于一个生...
六爻代表书籍 六爻预测好的书籍... 学六爻的书籍那些比较经典,最好适合初学者的。从古至今六爻类的书流传于世的非常少,六爻类最经典的几本书...
十二星座女生专属花卉 小葩画1... 狮子座的女生喜欢什么样的花1.狮子座的女生喜欢鲜艳、华丽、高贵的花。2.狮子座的女生通常有着自信、热...
客厅风水禁忌及化解 客厅推拉门... 客厅风水禁忌及解决方案客厅是家庭中最重要的空间之一,也是最容易受到风水影响的空间之一。在客厅里,我们...
吉凶参半牛兔在含义 牛兔相冲到... 吉凶参半牛兔在啥意思吉凶参半牛兔在是指属牛的和属兔的结婚以后生活吉凶各一半。丑牛与子鼠六合,因此最宜...
各生肖属相的车牌号码吉凶对照表... 十二生肖与车牌号的佳搭配 十二生肖车牌号吉凶对照表通常每个人的黄道十二宫都会影响车牌号码的运行模式,...
客厅西部尖角的风水 客厅有棱角... 客厅西南角最好的风水是什么?客厅西南角最好的风水是什么?客厅西南角最好的风水是什么?房子的方形风水是...
带昶字的女孩名字 带滢的女孩名... 长字命名的寓意及意义长字命名的寓意和意义是正直、坚强、努力、阳光、前途似景、忠诚。长是一个通用词。长...
六壬怎么算命 六壬掐指神算金口... 什么是六仁?刘仁是中国古代的算命方法,起源于汉代,是中国道教学派的经典之一。刘仁包括六个神:天乙、天...
四月二十九生肖运势 十二生肖鸡... 女1993农历四月二十九早上十点生辰八字是什么如何出生时间:公历 1993年 6月 18日 10点本...
带心字的游戏女孩名字大全集 游... 2020男孩怎么起名有内涵 带心字的男孩名字大全心繁体:心起名五行:金姓名学笔画:4画简体笔画:4画...
八字鬼谷子算命 鬼谷子精髓50... 什么是八字鬼谷子算命?八字鬼谷子算命,又称李静算命,是中国传统的民间算命方式。八字鬼谷子算命起源于六...
十二星座下个月的运势女生 十二... 白羊座下个月的运势女生白羊座女生本身就充满了无限活力和热情,下个月的运势也不会让你失望。职业上可能会...
号令天下手机吉凶预测 号令天下... 手机号怎么算吉凶?用最后四个手机号码除以80,然后减去整数部分(只留小数),再乘以80,就会得到一个...
命理十二生肖今年运势 明天运势... 命理十二生肖今年运势今年每年都有不同的转瞬即逝的岁月。对于不同的黄道十二宫来说,它每年都有自己独特的...
八字长生好吗 八字中帝旺到长生... 八字日坐长生一定富吗丁火曰元生于未月,余气通根,年支丙火也能助身,但于上两透旺食,生财耗身过甚,故命...
带日的名字女孩名字大全 起名带... 日字旁边的女孩名字大全日字旁边的女孩名字推荐1、诗晗、慧曦、Xi、仲晴2、小芸、小娟、会晴、若昕、敏...
号令天下固话号码测吉凶 查电话... 周易81测手机号码吉凶,号令天下手机号码测吉凶提起周易81测手机号码吉凶,大家都知道,有人问天下手机...