use*_*853 15 java concurrency multithreading executorservice java.util.concurrent
我可以在没有ExecutorService的情况下使用Callable线程吗?我们可以使用Runnable的实例和没有ExecutorService的Thread的子类,这个代码可以正常工作.但是这段代码始终如一:
public class Application2 {
public static class WordLengthCallable implements Callable {
public static int count = 0;
private final int numberOfThread = count++;
public Integer call() throws InterruptedException {
int sum = 0;
for (int i = 0; i < 100000; i++) {
sum += i;
}
System.out.println(numberOfThread);
return numberOfThread;
}
}
public static void main(String[] args) throws InterruptedException {
WordLengthCallable wordLengthCallable1 = new WordLengthCallable();
WordLengthCallable wordLengthCallable2 = new WordLengthCallable();
WordLengthCallable wordLengthCallable3 = new WordLengthCallable();
WordLengthCallable wordLengthCallable4 = new WordLengthCallable();
wordLengthCallable1.call();
wordLengthCallable2.call();
wordLengthCallable3.call();
wordLengthCallable4.call();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(0);
}
}
Run Code Online (Sandbox Code Playgroud)
使用ExecutorService,代码可以使用少量线程.我的错误在哪里?
Hol*_*ger 32
虽然interface
s通常是用预期的用例创建的,但它们绝不限于以这种方式使用.
给定一个Runnable
你可以将它提交给一个ExecutorService
,或者将它传递给构造函数,Thread
或者你可以run()
直接调用它的方法,就像你可以调用任何interface
方法而不涉及多线程.还有更多的用例,例如AWT,EventQueue.invokeLater(Runnable)
所以永远不要指望列表完整.
给定a Callable
,你有相同的选项,所以重要的是要强调,与你的问题不同,call()
直接调用不涉及任何多线程.它只是像任何其他普通方法调用一样执行方法.
由于没有构造函数Thread(Callable)
使用Callable
a Thread
而不ExecutorService
需要更多代码:
FutureTask<ResultType> futureTask = new FutureTask<>(callable);
Thread t=new Thread(futureTask);
t.start();
// …
ResultType result = futureTask.get(); // will wait for the async completion
Run Code Online (Sandbox Code Playgroud)
简单的直接答案是,如果要使用Callable创建和运行后台线程,则需要使用ExecutorService,当然,如果要获取Future对象或Futures集合,则需要使用ExecutorService.如果没有Future,您将无法轻松获取Callable返回的结果或轻松捕获生成的异常.当然你可以尝试将你的Callable包装在一个Runnable中,然后在一个Thread中运行它,但是这会引起一个问题,因为这样做你会失去很多.
编辑
你在评论中提问,
你是说像下面的代码,哪个有效?
public class Application2 {
public static class WordLengthCallable implements Callable {
public static int count = 0;
private final int numberOfThread = count++;
public Integer call() throws InterruptedException {
int sum = 0;
for (int i = 0; i < 100000; i++) {
sum += i;
}
System.out.println(numberOfThread);
return numberOfThread;
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(0);
}
public static class MyRunnable implements Runnable {
@Override
public void run() {
try {
new WordLengthCallable().call();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的回答:是的.链接"排序"中的代码有效.是的,它会创建后台线程,但会丢弃Callables中执行的计算结果,并忽略所有异常.这就是我所说的"因为这样做会让你失去很多".
例如,
ExecutorService execService = Executors.newFixedThreadPool(THREAD_COUNT);
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 0; i < THREAD_COUNT; i++) {
futures.add(execService.submit(new WordLengthCallable()));
}
for (Future<Integer> future : futures) {
try {
System.out.println("Future result: " + future.get());
} catch (ExecutionException e) {
e.printStackTrace();
}
}
Thread.sleep(1000);
System.out.println("done!");
execService.shutdown();
Run Code Online (Sandbox Code Playgroud)
编辑2
或者如果您希望在结果发生时返回结果,请使用CompletionService来包装您的ExecutorService,这是我以前从未尝试过的:
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompletionServiceExample {
public static class WordLengthCallable implements Callable<Integer> {
private Random random = new Random();
public Integer call() throws InterruptedException {
int sleepTime = (2 + random.nextInt(16)) * 500;
Thread.sleep(sleepTime);
return sleepTime;
}
}
private static final int THREAD_COUNT = 4;
public static void main(String[] args) throws InterruptedException {
ExecutorService execService = Executors.newFixedThreadPool(THREAD_COUNT);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(
execService);
for (int i = 0; i < THREAD_COUNT; i++) {
completionService.submit(new WordLengthCallable());
}
execService.shutdown();
try {
while (!execService.isTerminated()) {
int result = completionService.take().get().intValue();
System.out.println("Result is: " + result);
}
} catch (ExecutionException e) {
e.printStackTrace();
}
Thread.sleep(1000);
System.out.println("done!");
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class MainClass {
public static void main(String[] args) {
try {
Callable<String> c = () -> {
System.out.println(Thread.currentThread().getName());
return "true";
};
FutureTask<String> ft = new FutureTask<String>(c);
Thread t = new Thread(ft);
t.start();
String result = ft.get();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
Output:
Thread-0
true
*/
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21526 次 |
最近记录: |