一、Lock接口
java 1.5以後代替synchronized關鍵詞,更加靈活的,顯式的控制鎖。
1、
lock.lock()和lock.unlock() 代替 synchronized的作用範圍。
2、
condition.await() 代替 object.wait()
condition.signal() 代替 object.notify()
condition.signalAll() 代替 object.notifyAll()
3、同一個鎖可以包含多個condition,通過不同的condition,我們控制同一鎖對不同條件的加解。
生産者消費者優化:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ClassicalThread {
public static void main(String[] args) {
Resourse res = new Resourse();
new Thread(new Producer(res)).start();
new Thread(new Producer(res)).start();
new Thread(new Producer(res)).start();
new Thread(new Resumer(res)).start();
new Thread(new Resumer(res)).start();
new Thread(new Resumer(res)).start();
}
}
class Resourse {
private String name;
private int id = ;
private boolean flag = true;
private Lock lock = new ReentrantLock();
private Condition produceCondition = lock.newCondition();
private Condition resumeCondition = lock.newCondition();
public void produce(String name) {
lock.lock();
try {
while (!flag) {
try {
produceCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
System.out.println("生産" + name + " " + ++id);
flag = false;
resumeCondition.signal();
} finally {
lock.unlock();
}
}
public synchronized void resume() {
lock.lock();
try {
while (flag) {
try {
resumeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消費" + name + " " + id);
flag = true;
produceCondition.signal();
} finally {
lock.unlock();
}
}
}
class Producer implements Runnable {
private Resourse res;
public Producer(Resourse res) {
this.res = res;
}
@Override
public void run() {
while (true) {
res.produce("商品");
}
}
}
class Resumer implements Runnable {
private Resourse res;
public Resumer(Resourse res) {
this.res = res;
}
@Override
public void run() {
while (true) {
res.resume();
}
}
}
二、線程的結束
1、控制線程内的循環。
2、特殊情況:當該線程當機時,會出現主線程結束,但子線程依然當機,需要interrupt();
interrupt();既不是終結方法,也不是得到鎖的喚醒方法。作用是在存在需求時喚醒線程,但此時因為會存在共享變量的問題,是以不會執行代碼,而是使睡眠的線程抛出interrupted 異常。通過抛出異常,使該線程跳過共享變量的邏輯,繼續運作,結束循環。
即:
try{wait();}catch(interruptedException e){...}
代碼執行個體:
public class StopThread {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
boolean flag = true;
int i = ;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
@Override
public void run() {
lock.lock();
try {
while (flag) {
try {
condition.await();
} catch (InterruptedException e) {
flag = false;
}
System.out.println("第" + i++ + "次");
if (i == ) {
flag = false;
}
condition.signal();
}
} finally {
lock.unlock();
}
System.out.println("子線程結束");
}
});
t.start();
t.interrupt();
}
}
偷懶偷得自己感覺邏輯都有問題,呵呵哒~