1.线程间通信的常用方法
wait():令当前线程挂起并放弃CPU、同步资源,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问
notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
notifyAll ():唤醒正在排队等待资源的所有线程结束等待.
Java.lang.Object提供的这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则会报java.lang.IllegalMonitorStateException异常
package TestThread;
public class ThreadCommunication implements Runnable {
int num = 1;
@Override
public void run() {
while (true) {
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) { //线程交叉打印数字
notify();
if (num <= 100)
System.out.println(Thread.currentThread().getName() + ":" + num++);
else
break;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
@Test
public void testThreadCommunication(){
System.out.println("---------------start--------------------");
ThreadCommunication p = new ThreadCommunication();
Thread w1=new Thread(p);
Thread w2=new Thread(p);
w1.setName("窗口1");
w2.setName("窗口2");
w1.start();
w2.start();
try {
w1.join();
w2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("---------------end--------------------");
}
2.一个生产者消费者例子
生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
这里可能出现两个问题:
1. 生产者比消费者快时,消费者会漏掉一些数据没有取到。
2.消费者比生产者快时,消费者会取相同的数据。package TestThread;
class Clerk{
int product=0;
public synchronized void addProduct(){ //生产产品
if(product>=20){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
product++;
System.out.println(Thread.currentThread().getName()+":生产了第"+product +"个产品");
notifyAll();
}
}
public synchronized void consumeProduct(){ //消费产品
if(product<=0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+":消费了第"+product +"个产品");
product--;
notifyAll();
}
}
}
class Producer implements Runnable
{
Clerk clerk;
public Producer(Clerk clerk) {
this.clerk=clerk;
}
@Override
public void run() {
System.out.println("生产者开始生产产品");
while(true){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.addProduct();
}
}
}
class Consumer implements Runnable{
Clerk clerk;
public Consumer(Clerk clerk){
this.clerk=clerk;
}
@Override
public void run() {
System.out.println("消费者开始消费产品");
while(true){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.consumeProduct();
}
}
}
public class ProducerConsumer {
public static void main(String[] args) {
Clerk clerk=new Clerk();
Producer p=new Producer(clerk);
Consumer c=new Consumer(clerk);
Thread p1=new Thread(p);
Thread p2=new Thread(p);
Thread c1=new Thread(c);
Thread c2=new Thread(c);
p1.setName("生产者1");
p2.setName("生产者2");
c1.setName("消费者1");
c2.setName("消费者2");
p1.start();
p2.start();
c1.start();
c2.start();
}
}