鱼C论坛

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

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

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

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

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

x

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

package com.dayuanit.lesson049;

public class testlesson049 {
        
        //false--说明篮子为空 true--说明篮子不为空
        public static boolean flag = false;
        
        public static Object lock = new Object();//定义一把全局使用的锁
        
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                
                //生产者线程和消费者线程
                
                Thread producerThread = new Thread(new ProducerThread(), "producer thread");
                Thread customerThread = new Thread(new CustomerThread(), "customer thread");
                
                producerThread.start();
                customerThread.start();
        }

}

class ProducerThread  implements Runnable {
        public void run() {
                
                //不停的进行生产消费
                while (true) {
                        //需要先对全局的锁锁上,使用wait方法需要这一步,即释放这把锁
                        synchronized (testlesson049.lock) {
                                //先进行一次判断,如果篮子是有东西的,作为生产者停止向篮子里装东西,等待消费者消费
                                if (testlesson049.flag == true) {
                                        
                                        try {
                                                System.out.println("篮子是满的,消费者快来消费啊!!");
                                                System.out.println("-----------------------------");
                                                testlesson049.lock.wait();//等待机制
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                                }
                                
                                System.out.println("我是生产者,我能跑!!!");
                                
                                //往篮子里装东西
                                testlesson049.flag = true;
                                System.out.println(testlesson049.flag);
                                System.out.println("-----------------------------");
                                
                                
                                //执行完毕后稍微休息一下
                                try {
                                        Thread.sleep(2 * 1000);
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                                //告诉所有等待的线程,生产者的任务完成了
                                testlesson049.lock.notifyAll();
                        }
                }
        }
}

class CustomerThread  implements Runnable {
        public void run() {
                
                //不停的进行生产消费
                while (true) {
                        //需要先对全局的锁锁上,不然会出问题
                        synchronized (testlesson049.lock) {
                                //先进行一次判断,如果篮子为空,作为消费者停止从篮子里取东西,等待生产者生产
                                if (testlesson049.flag == false) {
                                        try {
                                                System.out.println("篮子是空的,生产者快干活啊!!");
                                                System.out.println("-----------------------------");
                                                testlesson049.lock.wait();
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                                }
                                
                                System.out.println("我是消费者,我拿到东西了!!!");
                                
                                //从篮子里取走东西
                                testlesson049.flag = false;
                                System.out.println(testlesson049.flag);
                                System.out.println("-----------------------------");
                                
                                //执行完毕后稍微休息一下
                                try {
                                        Thread.sleep(2 * 1000);
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                                //通知所有等待这把锁的线程,你们可以继续使用这把锁了
                                testlesson049.lock.notifyAll();
                        }
                }
        }
                
                
}
最佳答案
2020-4-20 14:22:25
萌萌哒的小虎崽 发表于 2020-4-20 14:13
那意思就是 生产者执行完毕以后,通知别人这把锁我不用了你们可以用的时候,这把锁的使用权还在它的手上 ...

。。。总觉得你的话哪里有点怪怪的感觉。但总体意思应该是没错的。唤醒其他线程的这个动作不会交出控制权。sleep或wait才会放开控制权
1587355311(1).jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

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

使用道具 举报

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

。。。总觉得你的话哪里有点怪怪的感觉。但总体意思应该是没错的。唤醒其他线程的这个动作不会交出控制权。sleep或wait才会放开控制权
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

搜噶搜噶,我明白了,谢谢大佬~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-3 16:18:01 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 23:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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