天下脸皮共十分
我占八分

join原理

Guarded Suspension

即保护性暂停,用在一个线程等待另一个线程的执行结果

image-20210102211155242

要点

  • 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject
  • 如果有结果不断从一个线程到另一个线程那么可以使用消息队列(见生产者/消费者)
  • JDK 中,join 的实现、Future 的实现,采用的就是此模式
  • 因为要等待另一方的结果,因此归类到同步模式

守护类

 package tech.ityoung.study.demo.jvm.juc;
 ​
 import lombok.extern.slf4j.Slf4j;
 ​
 @Slf4j
 public class GuardedObject {
     private Object lock = new Object();
     private Object response = null;
 ​
     public Object get(long waitTime) {
         synchronized (lock) {
             long begin = System.currentTimeMillis();
             long start = 0;
             while (response == null) {
                 if (waitTime - start <= 0) {
                     break;
                }
                 try {
                     lock.wait(waitTime - start);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
                 long now = System.currentTimeMillis();
                 start = now - begin;
            }
             log.info("get response completed");
             return response;
        }
    }
 ​
     public void complete(Object response) {
         synchronized (lock) {
             while (response != null) {
                 this.response = response;
                 lock.notifyAll();
                 break;
            }
        }
    }
 }

测试类

主线程等待子线程返回结果

等待时间内如果返回结果,则wait提前结束,否则wait时间后结束返回null

 package tech.ityoung.study.demo.jvm.juc;
 ​
 import lombok.extern.slf4j.Slf4j;
 ​
 import java.util.Random;
 ​
 @Slf4j
 public class GuardedObjectTest {
     public static void main(String[] args) throws InterruptedException {
         log.info("starting demo");
         GuardedObject guardedObject = new GuardedObject();
         new Thread(() -> {
             int response = 0;
             try {
                 response = getResponse();
            } catch (InterruptedException e) {
                 e.printStackTrace();
            }
             guardedObject.complete(response);
        }).start();
         Object o = guardedObject.get(5000);
         log.info("getting finished: {}", o);
    }
 ​
     private static int getResponse() throws InterruptedException {
         Thread.sleep(4000);
         return new Random(5).nextInt();
    }
 }
赞(1) 打赏
未经允许不得转载:Stephen Young » join原理
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏