1. 为什么要线程通信?
多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,并且我们希望他们有规律的执行, 那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。当然如果我们没有使用线程通信来使用多线程共同操作同一份数据的话,虽然可以实现,但是在很大程度会造成多线程之间对同一共享变量的争夺,那样的话势必为造成很多错误和损失!所以,我们才引出了线程之间的通信,多线程之间的通信能够避免对同一共享变量的争夺。
2.什么是线程通信?
多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。 就是多个线程在操作同一份数据时, 避免对同一共享变量的争夺。于是引出了等待唤醒机制:(wait()、notify())就是在一个线程进行了规定操作后,就进入等待状态(wait), 等待其他线程执行完他们的指定代码过后再将其唤醒(notify)。
(1)wait()
当一个线程调用对象的wait()方法时,该线程进入等待状态,并且释放该对象的锁,直到被另一个线程唤醒,才能重新拥有锁和继续执行。值得注意的是,在线程调用wait()前,必须获取该对象的监视器锁,且wait()方法必须放在synchronized代码块或synchronized方法中。
(2) notify()和notifyAll()
当notify()方法被调用时,唤醒一个等待当前对象的锁的线程,而notifyAll()被调用时,唤醒的是等待当前对象的锁的所有线程,这些线程去争夺该对象的监视器锁,最终只有一个线程成功获取对象的监视器锁。同样的,notify()和notifyAll()都必须放在synchronized代码块或synchronized方法中。
一个典型的线程间通信的例子就是生产者和消费者问题,这里我们用一个例子看一下:
import java.util.LinkedList;
public class Storage {
private static final int MAX_SIZE=10;//仓库最大容量
private static LinkedList<Object> list=new LinkedList<>();//存储产品的仓库
/**
* 生产者角色
*/
public static void produce(String threadName) {
synchronized (list) {
while(list.size()==MAX_SIZE) {
System.out.println("仓库已满");
try {
list.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
list.add(new Object());
System.out.println(threadName+"生产一个产品");
list.notifyAll();
}
}
/**
* 消费者角色
*/
public static void consume(String threadName) {
synchronized (list) {
while(list.size()==0) {
System.out.println("仓库已空");
try {
list.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
list.removeFirst();
System.out.println(threadName+"消费了一个产品");
list.notifyAll();
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
Storage.produce(Thread.currentThread().getName());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
Storage.consume(Thread.currentThread().getName());
}
}).start();
}
}
}
结果如下:
Thread-0生产一个产品
Thread-1消费了一个产品
Thread-2生产一个产品
Thread-4生产一个产品
Thread-3消费了一个产品
Thread-6生产一个产品
Thread-5消费了一个产品
Thread-7消费了一个产品
仓库已空
Thread-8生产一个产品
Thread-9消费了一个产品
395

被折叠的 条评论
为什么被折叠?



