我正在编写一个简单的线程,它只是运行一个进程并读取InputStream
。在读取输入时,如果它找到一个特定的字符串,它将布尔值设置为true。当我需要检查布尔值时,我通常这样做:
thread.start();
//some other code
thread.join();
thread.getBoolean();
或者我应该把Callable
和Future
一起使用吗?如果是这样,正确的用法应该是这样的?
Callable<Boolean> myTask = new Task();
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Boolean> future = executorService.submit(myTask);
//some other code
Boolean output = future.get();
System.out.println(output);
executorService.awaitTermination(3, TimeUnit.SECONDS);
executorService.shutdownNow();
在我看来,对这样的异步事件使用接口要好得多。它干净、快速、可靠。
我们将实现一个字符串处理器类,而不是一个裸线程类,它具有侦听器接口,以及一个process
方法,该方法将获取流以及要在流中查找的字符串。所以近似的实现如下:
StringProcessor.java
class StringProcessor {
public interface StringProcessorListener {
void onStringProcessingFinish(boolean found);
}
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private StringProcessorListener listener;
public StringProcessor(StringProcessorListener listener) {
this.listener = listener;
}
public void process(InputStream inputStream, String strToFind) {
executorService.execute(()-> {
// Do the processing here...
while(inputStream.availlable() > 0) {
// Processing... maybe some string building or something else...
// Processing code goes here...
// A string built check it out
if(str.equals(strToFind)) {
// The string what we look for is found, notify the listener with true
listener.onStringProcessingFinish(true);
return;
}
// If reached here then the string not found, notify with false
listener.onStringProcessingFinish(false);
}
});
}
}
我们可以从一个高级类中使用这个类,如下所示:
YourMainOrSuperiorClass.java
class YourMainOrSuperiorClass {
public static void main(String[] args) {
// Insantiate or get an input stream from where you wish...
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
// Search a string using the processor class
new StringProcessor(new StringProcessorListener {
@Override
public void onStringProcessingFinish(boolean found) {
if(found) {
// The string has been found, handle it
}
else {
// The String has not been found, handle it
}
}
})
.process(bufferedInputStream, "String to find");
// Maybe some more stuff to process from here...
}
}
如您所见,不需要使用异步接口模式阻塞任何线程。当您调用StringProcessor.process()
方法时,它将在其内部线程中处理字符串,而不会阻塞主线程,您不必等待它完成,相反,您可以同时处理更多代码。同时,一旦结果可用,
StringProcessor
将调用侦听器的onStringProcessingFinish()
方法,并将异步处理当主线程正在处理其他事情时,从主线程返回。
注意,主线程不应该返回,直到结果交付的情况下,你需要更新一些UI元素或其他东西在主线程。如果是这种情况,您可以使用布尔标志来管理它,当主线程执行完后,它的所有东西都会使用该标志进入一个繁忙的等待状态,直到交付结果。一旦结果交付,您就可以相应地设置布尔标志。这有点像使用线程阻塞方法之类的东西。