1. public class TestGuardedObjectV2 {
    2. public static void main(String[] args) {
    3. GuardedObjectV2 v2 = new GuardedObjectV2();
    4. new Thread(() -> {
    5. sleep(1);
    6. v2.complete(null);
    7. sleep(1);
    8. v2.complete(Arrays.asList("a", "b", "c"));
    9. }).start();
    10. Object response = v2.get(2500);
    11. if (response != null) {
    12. log.debug("get response: [{}] lines", ((List<String>) response).size());
    13. } else {
    14. log.debug("can't get response");
    15. }
    16. }
    17. }
    18. /**
    19. * 添加超时处理
    20. */
    21. @Slf4j(topic = "c.GuardedObjectV2")
    22. class GuardedObjectV2 {
    23. private Object response;
    24. private final Object lock = new Object();
    25. public Object get(long millis) {
    26. synchronized (lock) {
    27. // 1) 记录最初时间
    28. long last = System.currentTimeMillis();
    29. // 2) 已经经历的时间
    30. long timePassed = 0;
    31. while (response == null) {
    32. // 4) 假设 millis 是 1000,结果在 400 时唤醒了,那么还有 600 要等
    33. long waitTime = millis - timePassed;
    34. log.debug("waitTime: {}", waitTime);
    35. if (waitTime <= 0) {
    36. log.debug("break...");
    37. break;
    38. }
    39. try {
    40. lock.wait(waitTime);
    41. } catch (InterruptedException e) {
    42. e.printStackTrace();
    43. }
    44. // 3) 如果提前被唤醒,这时已经经历的时间假设为 400
    45. timePassed = System.currentTimeMillis() - last;
    46. log.debug("timePassed: {}, object is null {}", timePassed, response == null);
    47. }
    48. return response;
    49. }
    50. }
    51. public void complete(Object response) {
    52. synchronized (lock) {
    53. // 条件满足,通知等待线程
    54. this.response = response;
    55. log.debug("notify...");
    56. lock.notifyAll();
    57. }
    58. }
    59. }