线程间通信主要是以下三个方法:
* wait notify notifyAll
* 这三个方法定义在Object中,且都在同步代码块中使用
* wait:令当前线程挂起并放弃CPU 同步资源,让别的线程可以访问修改共享资源
* 当前线程排队等候再次对资源的访问
* notify:唤醒正在排队等待的同步资源的线程中优先级最高者结束等待
* notifyAll:唤醒正在排队等待的同步资源的所有线程
如下例 使用两个线程交替打印1-100
class PrintNum implements Runnable{
int num=1;
@Override
//存在线程安全问题,使用synchronized,但是这样没有进行线程间交替执行 需要用线程间的通信
public void run() {
while(true) {
synchronized(this) {
//进行唤醒操作(此步是必须得,不然造成了死锁)
notify();
if(num<=100) {
System.out.println(Thread.currentThread().getName()+":"+num);
num+=1;
}
try {
wait();//当前线程执行完 等待,记得需要唤醒,不然只打印两次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//
}
}
}
}
public class TestCom {
public static void main(String[] args) {
PrintNum p=new PrintNum();
Thread t1=new Thread(p);
Thread t2=new Thread(p);
t1.start();
t2.start();
}
}
运行结果:
下面再进行一个经典的生产者和消费者的案例:
class Clerk{
int product;
//生产产品
public synchronized void addProduct(){
if(product>=20) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
product++;
System.out.println(Thread.currentThread().getName()+"生产了"+product+"个产品");
notifyAll();
}
}
public synchronized void consumeProduct() {
if(product<=0) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
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(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clerk.addProduct();
}
}
}
class Customer1 implements Runnable{
Clerk clerk;
public Customer1(Clerk clerk) {
this.clerk=clerk;
}
public void run() {
System.out.println("消费者消费");
while(true) {
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clerk.consumeProduct();
}
}
}
public class TestPC {
public static void main(String[] args) {
Clerk clerk=new Clerk();
Producer p1=new Producer(clerk);
Customer1 c1=new Customer1(clerk);
Thread t1=new Thread(p1);//生产者
Thread t3=new Thread(p1);//生产者
Thread t2=new Thread(c1);//消费者
t1.setName("生产者");
t2.setName("消费者");
t3.setName("生产者2");
t1.start();
t2.start();
t3.start();
}
}
运行结果:
一个动态过程,因为生产者生产 消费者消费两者交替进行。
希望对大家有帮助。