美文网首页
简单说明 lock 锁和 Condition 的操作

简单说明 lock 锁和 Condition 的操作

作者: 咪雅先森 | 来源:发表于2019-05-17 10:55 被阅读0次

作用:使当前线程进入等待状,并交换执行执,等待被交换的当前执行线程唤醒,才可以继续执行,如果不被唤醒?
场景:多个线程操作同一个共享资源时使用。

Condition 是执行条件。类似传统技术中的 wait 的 notify 功能。
Condition 是基于一个 lock 而存在。
注意的是,Condition 的创建来自同一个 lock 对象,

Condition 也行 wait 也好,套路就是使用三个工具来完成三步套路。即,用两个线程,同时跑两个代码,并且用 while 不段的去读取一个条件,来判断自己是否应该唤醒对方。

步骤:
1.先lock住
2.通过 lock 拿到 condition。再进行操作如 await
3.然后多个线程开始 await、single
注意 await 会释放锁。

await()的作用是能够让其他线程访问竞争资源,所以挂起状态就是要释放竞争资源的锁。
package com.liukai.thread.lock.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by liukai on 2016/2/25.
 * 测试 Lock、Condition 代替 synchronized、wait
 * 例子来自 JDK Condition API 中的示例代码,阻塞队列的原理。
 * 注间的是,两个不同的方法里面的 等待 和 唤醒 是不同的对象
 */
public class TestCondition {

    private final Lock lock = new ReentrantLock();
    private final Condition full = lock.newCondition();
    private final Condition notFull = lock.newCondition();
    private int count = 0;
    private int takeptr = 0;
    private int putptr = 0;
    Object [] blockArray = new Object[100];

    public static void main(String[] args) {
        final TestCondition condition = new TestCondition();
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                try {
                    condition.put(new Object());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();

            new Thread(()->{
                try {
                    condition.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();

        }
    }

    public void put (Object element) throws InterruptedException {
        try {
            lock.lock();
            while (count == blockArray.length) {
                System.out.println("put: putptr = " + putptr + ", await");
                full.await();       //等待和唤醒用的不是同一个对象
            }
            System.out.println("put: putptr = " + putptr + ", 执行 put");
            blockArray[putptr] = element;
            if (++putptr == blockArray.length) {
                putptr = 0;
            }
            ++count;
            notFull.signal();
        } finally {
            lock.unlock();
        }
    }

    public Object take() throws InterruptedException {
        lock.lock();
        Object data = null;
        try {
            while (0 == count) {
                System.out.println("take: takeptr == " + takeptr + ",await");
                notFull.await();
            }
            System.out.println("take: takeptr = " + takeptr + ", 执行 take");
            data = blockArray[takeptr];
            if (++takeptr == blockArray.length) {
                takeptr = 0;
            }
            --count;
            full.signal();
            return data;
        } finally {
            lock.unlock();
        }
    }
}

相关文章

网友评论

      本文标题:简单说明 lock 锁和 Condition 的操作

      本文链接:https://www.haomeiwen.com/subject/lyjnaqtx.html