萌萌哒的小虎崽 发表于 2020-4-20 12:03:01

关于java锁的问题


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 ProducerThreadimplements 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 CustomerThreadimplements 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 13:36:02

当然是你理解错了,生产者和消费者的代码都放在while循环里,即使执行到最后一行语句,即使执行到notifyAll,线程的操控权仍然在自己手里,马上开始下一次循环。交出去线程控制权一定是"notify别人且自己sleep了",又或者执行到了wait语句

倒戈卸甲 发表于 2020-4-20 13:53:52

再通俗的解释一下就是,唤醒你只是让你拥有和别人一样的排队权力,并不是你马上就能开饭了

萌萌哒的小虎崽 发表于 2020-4-20 14:13:17

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

那意思就是 生产者执行完毕以后,通知别人这把锁我不用了你们可以用的时候,这把锁的使用权还在它的手上使得它能够再执行一次是吗?

倒戈卸甲 发表于 2020-4-20 14:22:25

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

。。。总觉得你的话哪里有点怪怪的感觉。但总体意思应该是没错的。唤醒其他线程的这个动作不会交出控制权。sleep或wait才会放开控制权

萌萌哒的小虎崽 发表于 2020-4-20 14:25:37

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

搜噶搜噶,我明白了,谢谢大佬~

zwhe 发表于 2020-6-3 16:18:01

{:7_136:}
页: [1]
查看完整版本: 关于java锁的问题