java中的简单超时

Simple timeout in java

任何人都可以指导我如何在java中使用简单的超时? 基本上在我的项目中,我正在执行一个语句br.readLine(),它正在读取调制解调器的响应。 但有时调制解调器没有响应。 为此我想添加一个超时。
我正在寻找像这样的代码:

1
2
3
4
5
try {
    String s= br.readLine();
} catch(TimeoutException e) {
    System.out.println("Time out has occurred");
}


你在寻找什么可以在这里找到。 可能存在一种更优雅的方式来实现这一点,但一种可能的方法是

选项1(首选):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
final Duration timeout = Duration.ofSeconds(30);
ExecutorService executor = Executors.newSingleThreadExecutor();

final Future<String> handler = executor.submit(new Callable() {
    @Override
    public String call() throws Exception {
        return requestDataFromModem();
    }
});

try {
    handler.get(timeout.toMillis(), TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
    handler.cancel(true);
}

executor.shutdownNow();

选项2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
final Duration timeout = Duration.ofSeconds(30);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

final Future<String> handler = executor.submit(new Callable() {
    @Override
    public String call() throws Exception {
        return requestDataFromModem();
    }
});

executor.schedule(new Runnable() {
    @Override
    public void run(){
        handler.cancel(true);
    }      
}, timeout.toMillis(), TimeUnit.MILLISECONDS);

executor.shutdownNow();

这些只是一个草案,所以你可以得到主要的想法。


示例1将无法编译。 它的这个版本编译并运行。 它使用lambda特征来缩写它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 * [RollYourOwnTimeouts.java]
 *
 * Summary: How to roll your own timeouts.
 *
 * Copyright: (c) 2016 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2016-06-28 initial version
 */

package com.mindprod.example;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static java.lang.System.*;

/**
 * How to roll your own timeouts.
 * Based on code at http://stackoverflow.com/questions/19456313/simple-timeout-in-java
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2016-06-28 initial version
 * @since 2016-06-28
 */


public class RollYourOwnTimeout
    {

    private static final long MILLIS_TO_WAIT = 10 * 1000L;

    public static void main( final String[] args )
        {
        final ExecutorService executor = Executors.newSingleThreadExecutor();

        // schedule the work
        final Future<String> future = executor.submit( RollYourOwnTimeout::requestDataFromWebsite );

        try
            {
            // where we wait for task to complete
            final String result = future.get( MILLIS_TO_WAIT, TimeUnit.MILLISECONDS );
            out.println("result:" + result );
            }

        catch ( TimeoutException e )
            {
            err.println("task timed out" );
            future.cancel( true /* mayInterruptIfRunning */ );
            }

        catch ( InterruptedException e )
            {
            err.println("task interrupted" );
            }

        catch ( ExecutionException e )
            {
            err.println("task aborted" );
            }

        executor.shutdownNow();

        }
/**
 * dummy method to read some data from a website
 */

private static String requestDataFromWebsite()
    {
    try
        {
        // force timeout to expire
        Thread.sleep( 14_000L );
        }
    catch ( InterruptedException e )
        {
        }
    return"dummy";
    }

}


使用以下代码行:

1
Thread.sleep(1000);

它会睡1秒钟。