线程锁的运用 两个线程循环输出、生产者 消费者

2019-12-09  本文已影响0人  最美下雨天

完成以下功能:两个线程交替输出,如此往复执行50次
读写锁

利用synchronized、wait、notify

必须额外定义一个标记变量

class Business {
    boolean flag = true;
 
    public synchronized void subRun() {
        while (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
            System.out.println("sub----------------------");
        flag = true;
        this.notify();
    }
 
    public synchronized void mainRun() {
        while (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
            System.out.println("main---------------------");
        flag = false;
        this.notify();
    }
}

利用Lock、Condition
class Business2 {
    Lock lock=new ReentrantLock();
    Condition condition_m=lock.newCondition();
    Condition condition_s=lock.newCondition();

    public  void subRun() {
        try {
            lock.lock();
            System.out.println("sub----------------------");
            condition_m.signal();
            condition_s.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            lock.unlock();
        }

    }

    public  void mainRun() {

        try {
            lock.lock();
            //注意先调用另一个condition的signal,再调用本condition的await
            //因为调用await后线程会阻塞住(阻塞住后signal执行不到了)并释放锁
            condition_s.signal();
            condition_m.await();
            System.out.println("main---------------------");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            lock.unlock();
        }


    }
}
生产者、消费者
class Business3 {

    static Object object=new Object();

    List<Integer> list=new ArrayList();

    public  void consume()
    {
        while (true)
        {

            synchronized (object)
            {
                if(list.size()<=0)
                {
                    try {
                        System.out.println("消费者进入阻塞状态,目前集合大小为:"+list.size());
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                else
                {
                    Integer integer=list.get(0);
                    list.remove(0);
                    System.out.println("消费者消费的元素为:"+integer);
                    object.notifyAll();
                }


            }
            //注意这个sleep的位置放到synchronized的外面,要不然不好演示效果
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }


    }



    public  void produce()
    {
        while (true)
        {
            synchronized (object)
            {

                if(list.size()>=10)
                {
                    try {
                        System.out.println("生产者进入阻塞状态,目前集合大小为:"+list.size());
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                else
                {
                    Integer integer=new Random().nextInt(1000);
                    list.add(integer);
                    System.out.println("生产者生产的元素为:"+integer);
                    object.notifyAll();

                }


            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }



    }

}

大概理解了,wait方法会导致本线程进入阻塞状态,并释放本线程持有的锁,notify会唤醒因为调用wait方法进入阻塞状态的线程,但是不会释放锁,所以即使其他线程被唤醒了,如果获取不到锁依然无法执行,必须等到本线程将锁释放后,然后大家一起争夺锁资源

上一篇 下一篇

猜你喜欢

热点阅读