1.wait、notify、notifyAll
1)每一個對象除了有一個鎖之外,還有一個等待隊列(wait set),當一個對象剛創建的時候,它的等待隊列是空的。
2)wait,告訴當前線程放棄監視器并進入睡眠狀態(進入等待隊列),直到其他線程進入同一個監視器并調用notify為止。
3)當調用對象的notify方法時,將從該對象的等待隊列中刪除一個任意選擇的線程,這個線程將再次成為可運行的線程。
4)當調用對象的notifyAll方法時,將從該對象的等待隊列中刪除所有等待的線程,這些線程將成為可運行的線程。
5)wait、nitify、nitifyAll這三個方法只能在synchronized方法中調用。
6)wait和notify主要用于producer-consumer這種關系中。
2.producer-consumer
class Test {
public static void main(String[] args) {
Queue q = new Queue();
Producer p = new Producer(q);
Consumer c = new Consumer(q);
p.start();
c.start();
}
}
class Producer extends Thread {
Queue q;
Producer(Queue q) {
this.q = q;
}
public void run() {
for (int i = 0; i < 10; i++) {
q.put(i);
System.out.println("Producer put " + i);
}
}
}
class Consumer extends Thread {
Queue q;
Consumer(Queue q) {
this.q = q;
}
public void run() {
while (true) {
System.out.println("Consumer get " + q.get());
}
}
}
class Queue {
int value;
boolean bFull = false;
public synchronized void put(int i) {
if (!bFull) {
value = i;
bFull = true;
notify();
}
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized int get() {
if (!bFull) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
bFull = false;
notify();
return value;
}
}
|
結果:
Producer put 0
Consumer get 0
Producer put 1
Consumer get 1
Consumer get 2
Producer put 2
Consumer get 3
Producer put 3
Consumer get 4
Producer put 4
Producer put 5
Consumer get 5
Consumer get 6
Producer put 6
Consumer get 7
Producer put 7
Consumer get 8
Producer put 8
Producer put 9
Consumer get 9
3.線程的終止
3.1設置一個flag變量。
public class ThreadLife {
public static void main(String[] args){
ThreadTest t=new ThreadTest();
new Thread(t).start();
for(int i=0;i<100;i++){
if(i==50) t.stopThread();
System.out.println(Thread.currentThread().getName()
+" is running.");
}
}
}
class ThreadTest implements Runnable{
private boolean flagRun=true;
public void stopThread(){
flagRun=false;
}
public void run(){
while(flagRun){
System.out.println(Thread.currentThread().getName()
+" is running.");
}
}
}
|
3.2使用中斷
使用interrupt()方法,會被wait方法的catch(InterruptedException)捕獲。
import java.util.Timer;
import java.util.TimerTask;
class Blocked extends Thread{
public Blocked(){
System.out.println("Starting Blocked");
start();
}
public void run(){
try{
synchronized(this){
wait();//Blocks
}
}catch(InterruptedException e){
System.out.println("Interrupted");
}
System.out.println("Exiting run()");
}
}
public class Interrupt {
static Blocked blocked=new Blocked();
public static void main(String[] args){
new Timer(true).schedule(new TimerTask(){
public void run(){
System.out.println("Preparing to interrupt");
blocked.interrupt();
blocked=null;//to release it
}
}, 2000);//run() after 2000 milliseconds
}
}
|
4.線程生命周期示意圖
5.參考資料
[1]Thinking in Java 3rd
[2]孫鑫視頻
[3]張孝祥,Java就業培訓教程,清華大學出版社
posted on 2007-08-19 05:14
前方的路 閱讀(2219)
評論(0) 編輯 收藏 所屬分類:
Java技術