Join的原理:
首先我们调用无参的join方法时实际上时调用了join(0)方法
public final void join() throws InterruptedException {
//无参的join首先实际上是调用了参数为长整型参数的join,传了个0
join(0);
}
join(0)方法首先会做参数检查,判断如果参数(最大等待时间),如果值小于0则抛出异常,如果传值等于0则让线程一直等待,循环检查如果线程还有存货就一直调用wait(0),如果大于0则计算出经过时间,计算出最大等待时间与经过实践的差值作为下一回合wait的等待时间参数
public final synchronized void join(final long millis)
throws InterruptedException {
//首先做了长整型参数检查,一旦发现最大等待时间小于0会抛出异常
if (millis > 0) {
//如果传值是大于0,那么
if (isAlive()) {
//开始时间
final long startTime = System.nanoTime();
//wait等待时间
long delay = millis;
do {
wait(delay);
//求出经历时间,计算出最大等待时间与经济事件的差值作为下一回合wait等待时间参数
} while (isAlive() && (delay = millis -
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0);
}
} else if (millis == 0) {
//如果传过来是0,实际上就是让线程一直等待,它回去循环检查如果线程还存货就一直调用wait(0)一直等待
while (isAlive()) {
wait(0);
}
} else {
throw new IllegalArgumentException("timeout value is negative");
}
}
异步模式之生产者/消费者
- 与保护性暂停中的GuardObject不同,不需要产生结果和消费结果的线程一一对应,生产者/消费者模式是异步模式
- 消费队列可以用来平衡生产和消费的线程资源
- 生产者仅仅负责产生结果数据,不需要关心数据如何处理,而消费者转型处理结果数据
- 消息队列是有容量限制的,队列满的时候不会再加入数据,空的时候不会再消耗数据
- JDK中各种阻塞队列,采用的就是这种模式
代码实现如下:
import java.security.GuardedObject;
import java.util.*;
import static java.lang.Thread.sleep;
public class Test01 {
public static void main(String[] args) {
MessageQueue messageQueue = new MessageQueue(2);
for (int i = 0; i <3;i++){
int id = i;
new Thread(()->{
messageQueue.put(new Meassage(id,"值"+id));
},"生产者"+i).start();
}
new Thread(()->{
while (true){
try {
sleep(1);
Meassage take = messageQueue.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"消费者").start();
}
}
class MessageQueue{
//消息的队列集合
private LinkedList<Meassage> list = new LinkedList<Meassage>();
//存储容量
private Integer capcity;
public MessageQueue(Integer capcity) {
this.capcity = capcity;
}
//从队列中取消息
public Meassage take(){
//检查队列是否为空
synchronized (list) {
while (list.isEmpty()){
try {
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Meassage meassage = list.removeFirst();
//提醒生产者可以生产了
list.notifyAll();
System.out.println("消费了"+meassage);
return meassage;}
}
//往队列中放消息
public void put(Meassage meassage){
synchronized (list){
while (list.size()==capcity){
try {
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//将消息加入队列尾部
list.addLast(meassage);
System.out.println("生产了"+meassage);
//提醒消费者可以消费了
list.notifyAll();
}
}
}
//消息类
final class Meassage{
private int id;
private Object value;
public int getId() {
return id;
}
public Object getValue() {
return value;
}
public Meassage(int id, Object value) {
this.id = id;
this.value = value;
}
}