美文网首页
Java Lock与Condition

Java Lock与Condition

作者: qingshuiting | 来源:发表于2019-02-20 11:17 被阅读0次

Java Lock与Condition

Lock接口提供的方法

void lock(); 
void lockInterruptibly() throws InterruptedException; // 获得锁,或者被interrupt;如果锁已经获得就无法interrupt
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;// 获得锁;或者等待一段时间获得锁;
//在等待的过程中可以被interrupt
Condition newCondition();// 详细的介绍在下一节中
void unlock(); // release the lock

既然在Lock中出现这么多的interrupt,那么就不得不说下Thread的状态,以及如何控制Thread的中断状态了。

Thread的状态与interrupt

Thread类中有三个关于interrupt的方法:

public void interrupt() // 主动中断线程,其实就是将中断标志位set为true
public static boolean interrupted()// 检测是否中断,但是调用会clear 中断标志位
public boolean isInterrupted()// 不会clear中断标志位

如何中断

条件:线程处于阻塞状态(调用sleep,join,wait,或者可中断的I/O上)。

操作:在阻塞状态的时候检测中断标志位,如果为true,那么就抛出InterruptedException,在异常抛出的时候会恢复中断标志位。

condition与Lock的配合使用

在没有Lock之前,线程通信的一些实现方式需要使用synchronizedObject的监控方法来进行实现。在后来Java提供了Lock以及condition。

获得condition的方法

在Lock接口中有一个方法为:但是这个方法并不是所有的实现Lock接口的实现类中支持
Condition newCondition();

支持newCondition的Lock有:ReentrantLockReentrantReadWriteLock.WriteLock

condition的使用 vs Object monitor的使用

condition支持的操作:

// wait
void await() throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
long awaitNanos(long nanosTimeout) throws InterruptedException;
void awaitUninterruptibly();
boolean awaitUntil(Date deadline) throws InterruptedException;
// signal
void signal();
void signalAll();

condition使用的模板:

// wait 模板,signal 模板
lock.lock();
try{
    // wait 条件:一般都是使用while
    while(meet the condition){
        condition.await();
    }
    // 满足条件进行一系列操作
    ... your operation
    otherCondition.signal()// otherCondition.signalAll()
    
}catch(){

}finally{
    lock.unlock();
}

区别notify、signal与notifyAll、signalAll

通过下一段代码来查看notify和notifyAll的区别。

import java.util.concurrent.TimeUnit;

/**
 * Created by liukun on 18/10/4.
 */
public class Test {

    private static Object object = new Object();
    private static int value = 0;

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            final int tempi = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    function(tempi);
                }
            }).start();
        }
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        value = 1;
        synchronized (object) {
            System.out.println("notify ------");
            object.notifyAll();
        }
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void function(int i) {
        System.out.println("第" + i + "个 function被调用");
        synchronized (object) {
            System.out.println("第" + i + "个 进入synchronize");
            while (value == 0) {
                try {
                    System.out.println("第" + i + "个 准备wait");
                    object.wait();
                    System.out.println("第" + i + "个 被唤醒");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("第" + i + "个 function要退出");
    }
}

其中启动了5个线程,都处于wait的状态。然后main thread,调用了notify或者notifyAll。

输出情况:
调用notify的时候,只会有一个thread被唤醒(awakened)。当调用notifyAll的时候,会把所有都在等待对应这个object的monitor的threads都唤醒。

同理condition的signal和signalAll是一样的。

相关文章

网友评论

      本文标题:Java Lock与Condition

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