zoukankan      html  css  js  c++  java
  • ReentrantLock的使用

    关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式。
    类ReentrantLock同样可以实现该功能,但是要借助于Condition对象。它具有更好的灵活性,比如可以实现多路通知功能,也就是在一个Lock对象里面可以创建多个Condition(对象监视器)实例,线程对象可以注册在指定Condition中,从而有选择性的进行线程通知,在调度线程上更加灵活
    使用notify和notifyAll方法进行通知时,被通知的线程是由JVM随机选择的,但是ReentrantLock结合Condition可以实现前面介绍过的“选择性通知”,这个功能是非常重要的。
    synchronized相当于整个Lock对象中只有单一的Condition对象,所有线程都注册在它一个对象上,线程开始notifyAll()时,需要通知所有waiting的线程,没有选择权,会出现相当大的效率问题

    简单例子:

    public class TestLock implements Runnable {
        public static ReentrantLock lock = new ReentrantLock();
    
        @Override
        public void run() {
            try {
                lock.lock();
                for (int i = 0; i < 5; i++) {
                    System.out.println(i);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            TestLock lock = new TestLock();
            new Thread(lock).start();
            new Thread(lock).start();
            new Thread(lock).start();
        }
    }

    得到结果是顺序打印。

    condition调用await()方法后,会释放lock,接收到同一个condition的signal后线程需要重新获得锁,

    使用Condition例子:

    public class TestLock {
        public static ReentrantLock lock = new ReentrantLock();
        public static Condition newCondition = lock.newCondition();
    
        public static void main(String[] args) {
            class MyRunnable1 implements Runnable {
                @Override
                public void run() {
                    try {
                        lock.lock();
                        System.out.println("myRunnable1:await:begin");
                        newCondition.await();
                        System.out.println("myRunnable1:await:end");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
            }
            ;
    
            class MyRunnable2 implements Runnable {
                @Override
                public void run() {
                    try {
                        lock.lock();
                        System.out.println("myRunnable2:signal:begin");
                        newCondition.signal();
                        System.out.println("myRunnable2:signal:end");
                    } finally {
                        lock.unlock();
                    }
                }
            }
    
            new Thread(new MyRunnable1()).start();
            new Thread(new MyRunnable2()).start();
        }
    }

    结果:

  • 相关阅读:
    wifi 天线
    Ubuntu下通过SSH远程登录服务器的方法
    wifi 天线
    免费20G全能空间正在火爆开放中。。。。。要的抓紧时间申请了.
    php设计模式 Mediator (中介者模式)
    DEDE图片集上传图片时出错显示(FILEID)的解决办法
    SPL spl_autoload_register与__autoload方法使用示例浅谈
    mysql_fetch_array()和mysql_fetch_assoc()两个函数的区别
    nginx多站设置
    php中echo(),print(),print_r()的区别
  • 原文地址:https://www.cnblogs.com/grasp/p/10109438.html
Copyright © 2011-2022 走看看