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
前方的路 阅读(2211)
评论(0) 编辑 收藏 所属分类:
Java技术