关于java:话说-Lock-condition

51次阅读

共计 5066 个字符,预计需要花费 13 分钟才能阅读完成。

之前文章有写 wait/notify/notifyAll

Condition 作用相似,可能会多一些性能 比方:反对不响应中断、可指定工夫点完结期待、可多条件(new 多个 Condition)

Condition 的 await 与 wait 相似 必须在获取锁的时候能力 await

一、应用

/**
 * @author 木子的昼夜
 */
public class ConditionTest {public static Lock lock = new ReentrantLock();
    //
    public static Condition cd01 = lock.newCondition();
    public static void main(String[] args) throws InterruptedException {ConditionTest test = new ConditionTest();
        new Thread(test::say01).start();
        Thread.sleep(5000);
        new Thread(test::say02).start();}

    /**
     * 说:我饿了
     */
    public void say01(){
        try{lock.lock();
            System.out.println("我饿了");
            cd01.await();
            System.out.println("吃饱了");
        } catch (Exception e){e.printStackTrace();
        } finally {lock.unlock();
        }
    }
    /**
     * 说:饭好了
     */
    public void say02(){
        try{lock.lock();
            cd01.signal();
            System.out.println("开饭了");
        } catch (Exception e){e.printStackTrace();
        } finally {lock.unlock();
        }
    }
}
输入后果:我饿了
开饭了
吃饱了 

二、不响应中断

看一下 say01 say02 可中断 say03 不可中断

public class ConditionTest02 {public static Object obj = new Object();
    public static Lock lock = new ReentrantLock();
    public static Condition cd01 = lock.newCondition();
    public static void main(String[] args) throws InterruptedException {ConditionTest02 test = new ConditionTest02();
        Thread thread = new Thread(test::say01);
        Thread thread02 = new Thread(test::say02);
        Thread thread03 = new Thread(test::say03);


        thread.start();
        thread02.start();
        thread03.start();

        // 饿他们 5 秒钟
        Thread.sleep(5000);

        // 中断
        thread.interrupt();
        thread02.interrupt();
        // say03 会中断失败
        thread03.interrupt();}

    /**
     * 说:小强饿了
     */
    public void say01(){
        try{lock.lock();
            System.out.println("小强饿了");
            System.out.println("小强期待投食");
            cd01.await();
            System.out.println("小强吃饱了");
        }catch (InterruptedException e){System.out.println("小强进来觅食了");
        }catch (Exception e){e.printStackTrace();
        } finally {lock.unlock();
        }
    }

    /**
     * 说:小明饿了
     */
    public void say02(){
        try{synchronized (obj){System.out.println("小明饿了");
                System.out.println("小明期待投食");
                obj.wait();
                System.out.println("小明吃饱了");
            }
        } catch (InterruptedException e){System.out.println("小明进来觅食了");
        }
    }

    /**
     * 说:小月鸟饿了 中断无用 
     */
    public void say03(){
        try{lock.lock();
            System.out.println("小月鸟饿了");
            System.out.println("小月鸟期待投食");
            cd01.awaitUninterruptibly();
            System.out.println("小月鸟吃饱了");
        }catch (Exception e){System.out.println("小月鸟进来觅食了");
            e.printStackTrace();} finally {lock.unlock();
        }
    }
   
}

输入后果:小明饿了
小明期待投食
小强饿了
小强期待投食
小月鸟饿了
小月鸟期待投食
小明进来觅食了
小强进来觅食了 

三、超时进行 wait

condition 能够 await 一段时间 本人意识到 没人理他 而后就完结 await 了

Object 的 wait 也能够指定超时工夫

public class ConditionTest03 {public static Lock lock = new ReentrantLock();
    //
    public static Condition cd01 = lock.newCondition();
    public static void main(String[] args)   {ConditionTest03 test = new ConditionTest03();
        new Thread(test::say01).start();}

    /**
     * 说:我饿了
     */
    public void say01(){
        try{lock.lock();
            System.out.println("我饿了");
            System.out.println("期待投喂");
            //

            // 这个须要的单位是毫奥妙  也就是秒 *1000*1000000  也就是 5000000000L 毫奥妙 = 5 秒
            // 也能够这样获取 nanos 就等于 也就是 5000000000L
            long nanos = TimeUnit.SECONDS.toNanos(5);

            long res = cd01.awaitNanos(5000000000L);
            // 也能够这样 返回 true  false 
            // boolean res = cd01.await(10,TimeUnit.SECONDS);
            // 超时
            if (res <= 0){System.out.println("没人投喂  我本人觅食去");
            } else {System.out.println("有人投喂 我吃饱了");
            }
        } catch (Exception e){e.printStackTrace();
        } finally {lock.unlock();
        }
    }
}

四、指定工夫

能够指定到指定某个工夫点 就完结 wait

public class LockTest04 {
    // 新建锁
    public static Lock lock = new ReentrantLock(false);
    public static Condition cd = lock.newCondition();

    public static void main(String[] args) throws InterruptedException {new Thread(()->{
            try {lock.lock();
                long l = System.currentTimeMillis();
                l = l +1000*10;
                Date date = new Date(l);
                boolean  res = cd.awaitUntil(date);
                if(res) {System.out.println("被告诉");
                } else {System.out.println("没人告诉  到时见我本人走了");
                }
            } catch (Exception e){e.printStackTrace();
            }finally {lock.unlock();
            }
        }).start();}
}

五、创立多个 condition

这里举个例子:小强 和 小月月 两个人在玩儿玩具 小强玩会儿 不玩儿了给小月月 小月月不玩了再给小强

public class PlayTest {public static Lock lock = new ReentrantLock();
    public static Condition cd01 = lock.newCondition();
    public static void main(String[] args) {PlayTest test = new PlayTest();
        new Thread(test::xiaoqiangPlay).start();
        new Thread(test::xiaoxuexuePlay).start();}

    // 小强玩儿
    public void xiaoqiangPlay(){
        try {while (true){lock.lock();
                System.out.println("小强玩儿");
                Thread.sleep(5000);
                // 告诉他人玩儿
                cd01.signal();
                // 本人等着他人告诉
                cd01.await();}
        } catch (Exception e) {e.printStackTrace();
        } finally {lock.unlock();
        }
    }
    // 下月月玩
    public void xiaoxuexuePlay(){
        try {while(true){lock.lock();
                System.out.println("小月月玩儿");
                Thread.sleep(5000);
                // 告诉他人玩儿
                cd01.signal();
                // 本人等着他人告诉
                cd01.await();}
        } catch (Exception e) {e.printStackTrace();
        } finally {lock.unlock();
        }
    }
}

能够应用两个 condition

public class PlayTest02 {public static Lock lock = new ReentrantLock();
    public static Condition cd01 = lock.newCondition();
    public static Condition cd02 = lock.newCondition();
    public static void main(String[] args) {PlayTest02 test = new PlayTest02();
        new Thread(test::xiaoqiangPlay).start();
        new Thread(test::xiaoxuexuePlay).start();}

    // 小强玩儿
    public void xiaoqiangPlay(){
        try {while (true){lock.lock();
                System.out.println("小强玩儿");
                Thread.sleep(5000);
                // 告诉他人玩儿
                cd01.signal();
                // 本人等着他人告诉
                cd02.await();}
        } catch (Exception e) {e.printStackTrace();
        } finally {lock.unlock();
        }
    }
    // 下月月玩
    public void xiaoxuexuePlay(){
        try {while(true){lock.lock();
                System.out.println("小月月玩儿");
                Thread.sleep(5000);
                // 告诉他人玩儿
                cd02.signal();
                // 本人等着他人告诉
                cd01.await();}
        } catch (Exception e) {e.printStackTrace();
        } finally {lock.unlock();
        }
    }
}

两个 condition 互不烦扰,能够指定 condition await / signal

condition 的 signalAll 与 notifyAll 相似 不再代码演示

六、总结

  1. 创立 Condition (可创立多个 互不影响)
  2. 必须在 lock 获取锁之后能力应用
  3. await 反对不相应中断、超时(Object wait 也反对)、指定工夫点完结
  4. signal 只会唤醒一个线程 signalAll 会唤醒所有线程

有问题能够留言哦,可也以公众号留言(回复快):

正文完
 0