多线程基础

2018-08-23  本文已影响0人  JayZJU

多线程基础总结

一、线程中断

interrupt方法用来请求终止线程。

1. interrupt置位中断标志位

当对一个线程调用interrupt方法时,线程的中断标志位被置位,表示请求终止线程。

// 线程将中断作为终止程序的请求
Runnable r1 = () -> {
    try {
        Thread.sleep(1000);  // 阻塞
        // 正常情况下检测中断标志位
        while (!Thread.currentThread().isInterrupted()) {
            // has work to do

        }
    } catch (InterruptedException e) {
        // 线程在阻塞的时候被中断
    } finally {
        // 清除资源
    }
    // 退出程序
};

2. 如果线程被阻塞,调用interrupt方法,阻塞调用会被InterruptedException异常中断。

此时,应捕获InterruptedException异常。

// 阻塞的时候被中断,会清除中断标识位,并抛出中断异常
Runnable r2 = () -> {
    try {
        while (true) {
            // has work to do
            Thread.sleep(1000); // 睡眠的时候产生中断
        }
    } catch (InterruptedException e) {
        // 线程在阻塞的时候被中断
    } finally {
        // 清除资源
    }
    // 退出程序
};

3.两个类似的方法interruptedisInterrupted

4.使用不当及纠正

void mySubTask() {
    ...
    try {sleep(delay)}
    catch (InterruptedException e) {} // 被忽略
}

上述代码中的中断异常不应被忽略,有以下两种选择:

二、线程状态

线程状态转换图

BlockedWaiting的区别:

三、锁对象

1.可重入锁ReentrantLock

模板代码:�

Lock myLock = new ReentrantLock();
myLock.lock(); // 互斥、可重入
try {
    // 临界区
} finally {
    myLock.unlokc();
}

2.条件Condition

**`Lock`下更加细粒度的并发控制.**

`Condition`用来控制、管理那些已经获得了一个锁,但是却因为不满足条件而不能做有用工作的线程。一个锁对象可以有一个或多个条件对象。
private Lock bankLock = new ReentrantLock();;
private Condition sufficientFunds = bankLock.newCondition(); // 足够的资金

// sufficientFunds.await(); ---> sufficientFunds.signalAll();
public void transfer(int from, int to, int amount) {
    bankLock.lock();
    try {
        while(account[from] < amount) {
            sufficientFunds.await(); // 金额不足,阻塞
        } 
        // transfer funds
        sufficientFunds.signalAll(); // signalAll()
    } finally {
        bankLock.unlock();
    }
}

四、synchronized关键字

Java中的每一个对象都有一个内部锁。如果一个方法用synchronized声明,则对象的锁将保护整个方法。

public synchronized void method() {
    // method body
}
// 等价于
public void method() {
    this.intrinsicLock.lock();
    try {
        // method body
    } finally {
        this.intrinsicLock.unlock();
    }
}

内部对象锁只有一个条件,调用wait()添加一个线程到条件的等待集中,notifyAll/notify()方法解除等待线程的阻塞状态。

intrinsicCondition.await() ---- wait()
intrinsicCondition.signalAll() ---- notifyAll()
上一篇 下一篇

猜你喜欢

热点阅读