public class LockDemo { public static void main(String[] args) throws InterruptedException { Phone phone = new Phone(); phone.call(); new Thread(()->{ }, "张三").start(); new Thread(()->{ phone.msg(); }, "李四").start(); } } class Phone{ public synchronized void call() throws InterruptedException { TimeUnit.SECONDS.sleep(2); System.out.println("打电话!"); } public synchronized void msg(){ System.out.println("发短信!"); } }解释一下代码:
1. 新建一个 Phone 类咯,里面有两个被 synchronized 关键字修饰的 function。
2. 然后主线程(main),new 一个 Phone 对象给两个线程去调用(记住啊,new 一个就够了,老婆一个就够了,不要搞太多,因为有些事情太多就会出事情)。
3. 然后在两个线程里面执行同个对象的不同 function,在打电话的 function里面加一个休眠(不要用 Thread.sleep(),这个面试的时候比较装逼,是 JUC 里面的东西)。
执行结果:猜猜是什么?我猜你会猜错,先别看答案,思考一下。
是先打电话,还是先发短信。
正确答案:其实我猜的是:
1. 发短信
2. 打电话
我个人觉得是主线程里面应该是按顺序来执行的,先是 打电话 ,再是 发信息 没错。
但是打电话里面有 2s 的睡眠时间,按照我们现在的计算机水平,早已经跳到主线程里面的 发信息 来了。
为什么还等打电话执行完再执行发短信啊,这不符合线程的逻辑啊??
带着一百个为什么,“乘风破浪会有时”,其实是 synchronized 关键字搞的鬼。
想理解其中的原理,那么务必要知道 synchronized 是什么?锁的是什么?
synchronized 是什么?为什么会出现这个鬼东西?
这个问题是真的棒,首先有这个问题,你应该要思考一下为什么要有 线程 这个东西。
线程:线程他是cpu执行的最小单元,一个程序里面有很多个线程。
对于没有学过 *** 作系统读这句话,可能有点懵逼。跟在套环一样啊,一个新知识点套另一个知识点。
今天 可乐 就给你来个简单的解释。
程序就是能在计算机执行的指令呗。不理解其实也没关系,知道他有什么实例就行了,qq程序,微信程序...,不陌生吧。这就是程序。
那一个程序有多个线程又怎么理解。
线程其实也不难理解,一个程序里面肯定要分很多个线程去搞的啦。
例如,你在刷微信朋友圈,那微信朋友圈算是一个线程吧,那总得分一条线程出来聊天那里吧(不然,你刷朋友圈收不到 那些女朋友 发来的信息,那很不符合逻辑)
上面解释完多线程的应用场景还有为什么需要多线程。
那么多线程带来的问题也是不容忽视的,也就是我们所说到的 并发问题 啦。划重点,面试会问。
并发是什么东西?好像有个词跟他挺像,并行?
并发,搞个例子解释下。12306买票,买过吧哈哈哈。就是这个鬼东西啦。
这个 票 很多人想买,那如果一个时刻里面只剩一张票,那一堆人来,岂不是很乱,明明网站显示仅剩一张票,我购买了,他也购买了,她也购买了?这不瞎搞吗?
这个时候就好像去食堂买饭一样,只剩一个饭盒,大家都冲过去,这打饭阿姨手中这个饭都被人抢烂了。
那这个时候肯定是要排队的啦,一个人慢慢来,排得到(锁)就有,排不到饿饿其实也没很大关系。
并发,就是一个一个来。
并行,顾名思义,那就是同时搞多个东西啦。一边吃饭一边看电视,就是这么个道理哦。
那么解决并发问题,无非就是需要个 排队 还有一把 锁(锁上其他人乱来)。
就好像公共厕所问题一样。排队一个人一个人来,排到的进去拉*要把锁锁上,避免有些人不知道就冲了进去,这还挺不安全。
那么 synchronized 就是有着排队和锁的功能,从而来解决并发问题。
上面的例子在搞过来。
public synchronized void call() throws InterruptedException { TimeUnit.SECONDS.sleep(2); System.out.println("打电话!"); } public synchronized void msg(){ System.out.println("发短信!"); }
看第一个函数,虽然她休眠了,你以为他会执行第二个函数。但是只是你以为。
synchronized 就是把这个 phone 对象给锁了,因为先执行 call 函数,两条线程有 *** 作着同一个对象,那必定意味着这个对象需要解锁之后,其他才能使用。这下明白了吧
觉得写得还看的懂的,点个赞,关注一下哈哈哈。想看其他内容欢迎留言,不定期更新。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)