鱼C论坛

 找回密码
 立即注册
查看: 3082|回复: 6

[已解决]关于java锁的问题

[复制链接]
发表于 2020-4-20 12:03:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

Java中刚刚释放掉锁的线程在再次抢锁的速度上是不是会有优势啊?看这里的执行结果,一直都是两个线程连续执行两次,是巧合吗还是?


  1. package com.dayuanit.lesson049;

  2. public class testlesson049 {
  3.        
  4.         //false--说明篮子为空 true--说明篮子不为空
  5.         public static boolean flag = false;
  6.        
  7.         public static Object lock = new Object();//定义一把全局使用的锁
  8.        
  9.         public static void main(String[] args) {
  10.                 // TODO Auto-generated method stub
  11.                
  12.                 //生产者线程和消费者线程
  13.                
  14.                 Thread producerThread = new Thread(new ProducerThread(), "producer thread");
  15.                 Thread customerThread = new Thread(new CustomerThread(), "customer thread");
  16.                
  17.                 producerThread.start();
  18.                 customerThread.start();
  19.         }

  20. }

  21. class ProducerThread  implements Runnable {
  22.         public void run() {
  23.                
  24.                 //不停的进行生产消费
  25.                 while (true) {
  26.                         //需要先对全局的锁锁上,使用wait方法需要这一步,即释放这把锁
  27.                         synchronized (testlesson049.lock) {
  28.                                 //先进行一次判断,如果篮子是有东西的,作为生产者停止向篮子里装东西,等待消费者消费
  29.                                 if (testlesson049.flag == true) {
  30.                                        
  31.                                         try {
  32.                                                 System.out.println("篮子是满的,消费者快来消费啊!!");
  33.                                                 System.out.println("-----------------------------");
  34.                                                 testlesson049.lock.wait();//等待机制
  35.                                         } catch (InterruptedException e) {
  36.                                                 // TODO Auto-generated catch block
  37.                                                 e.printStackTrace();
  38.                                         }
  39.                                 }
  40.                                
  41.                                 System.out.println("我是生产者,我能跑!!!");
  42.                                
  43.                                 //往篮子里装东西
  44.                                 testlesson049.flag = true;
  45.                                 System.out.println(testlesson049.flag);
  46.                                 System.out.println("-----------------------------");
  47.                                
  48.                                
  49.                                 //执行完毕后稍微休息一下
  50.                                 try {
  51.                                         Thread.sleep(2 * 1000);
  52.                                 } catch (InterruptedException e) {
  53.                                         // TODO Auto-generated catch block
  54.                                         e.printStackTrace();
  55.                                 }
  56.                                 //告诉所有等待的线程,生产者的任务完成了
  57.                                 testlesson049.lock.notifyAll();
  58.                         }
  59.                 }
  60.         }
  61. }

  62. class CustomerThread  implements Runnable {
  63.         public void run() {
  64.                
  65.                 //不停的进行生产消费
  66.                 while (true) {
  67.                         //需要先对全局的锁锁上,不然会出问题
  68.                         synchronized (testlesson049.lock) {
  69.                                 //先进行一次判断,如果篮子为空,作为消费者停止从篮子里取东西,等待生产者生产
  70.                                 if (testlesson049.flag == false) {
  71.                                         try {
  72.                                                 System.out.println("篮子是空的,生产者快干活啊!!");
  73.                                                 System.out.println("-----------------------------");
  74.                                                 testlesson049.lock.wait();
  75.                                         } catch (InterruptedException e) {
  76.                                                 // TODO Auto-generated catch block
  77.                                                 e.printStackTrace();
  78.                                         }
  79.                                 }
  80.                                
  81.                                 System.out.println("我是消费者,我拿到东西了!!!");
  82.                                
  83.                                 //从篮子里取走东西
  84.                                 testlesson049.flag = false;
  85.                                 System.out.println(testlesson049.flag);
  86.                                 System.out.println("-----------------------------");
  87.                                
  88.                                 //执行完毕后稍微休息一下
  89.                                 try {
  90.                                         Thread.sleep(2 * 1000);
  91.                                 } catch (InterruptedException e) {
  92.                                         // TODO Auto-generated catch block
  93.                                         e.printStackTrace();
  94.                                 }
  95.                                 //通知所有等待这把锁的线程,你们可以继续使用这把锁了
  96.                                 testlesson049.lock.notifyAll();
  97.                         }
  98.                 }
  99.         }
  100.                
  101.                
  102. }
复制代码

最佳答案
2020-4-20 14:22:25
萌萌哒的小虎崽 发表于 2020-4-20 14:13
那意思就是 生产者执行完毕以后,通知别人这把锁我不用了你们可以用的时候,这把锁的使用权还在它的手上 ...

。。。总觉得你的话哪里有点怪怪的感觉。但总体意思应该是没错的。唤醒其他线程的这个动作不会交出控制权。sleep或wait才会放开控制权
1587355311(1).jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-4-20 13:36:02 From FishC Mobile | 显示全部楼层
当然是你理解错了,生产者和消费者的代码都放在while循环里,即使执行到最后一行语句,即使执行到notifyAll,线程的操控权仍然在自己手里,马上开始下一次循环。交出去线程控制权一定是"notify别人且自己sleep了",又或者执行到了wait语句
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-20 13:53:52 From FishC Mobile | 显示全部楼层
再通俗的解释一下就是,唤醒你只是让你拥有和别人一样的排队权力,并不是你马上就能开饭了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-20 14:13:17 | 显示全部楼层
倒戈卸甲 发表于 2020-4-20 13:36
当然是你理解错了,生产者和消费者的代码都放在while循环里,即使执行到最后一行语句,即使执行到notifyAll ...

那意思就是 生产者执行完毕以后,通知别人这把锁我不用了你们可以用的时候,这把锁的使用权还在它的手上使得它能够再执行一次是吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-20 14:22:25 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
萌萌哒的小虎崽 发表于 2020-4-20 14:13
那意思就是 生产者执行完毕以后,通知别人这把锁我不用了你们可以用的时候,这把锁的使用权还在它的手上 ...

。。。总觉得你的话哪里有点怪怪的感觉。但总体意思应该是没错的。唤醒其他线程的这个动作不会交出控制权。sleep或wait才会放开控制权
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-20 14:25:37 | 显示全部楼层
倒戈卸甲 发表于 2020-4-20 14:22
。。。总觉得你的话哪里有点怪怪的感觉。但总体意思应该是没错的。唤醒其他线程的这个动作不会交出控制权 ...

搜噶搜噶,我明白了,谢谢大佬~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-3 16:18:01 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-18 08:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表