我尝试过创建和执行ThreadPoolExecutor
int poolSize = 2;
int maxPoolSize = 3;
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(2);
Run Code Online (Sandbox Code Playgroud)
如果我连续尝试7日,8日......任务
threadPool.execute(task);
Run Code Online (Sandbox Code Playgroud)
在队列达到最大大小后,
它开始抛出"RejectedExecutionException".意味着我失去了添加这些任务.
在这里,如果BlockingQueue缺少任务,那么它的作用是什么?意味着它为什么不等待?
从BlockingQueue的定义
一个队列,它还支持在检索元素时等待队列变为非空的操作,并在存储元素时等待队列中的空间可用.
为什么我们不能使用linkedlist(正常队列实现而不是阻塞队列)?
我有一个简单的java ExecutorService运行一些任务对象(实现Callable).
ExecutorService exec = Executors.newSingleThreadExecutor();
List<CallableTask> tasks = new ArrayList<>();
// ... create some tasks
for (CallableTask task : tasks) {
Future future = exec.submit(task);
result = (String) future.get(timeout, TimeUnit.SECONDS);
// TASKS load some classes and invoke their methods (they may create additional threads)
// ... catch interruptions and timeouts
}
exec.shutdownNow();
Run Code Online (Sandbox Code Playgroud)
在完成所有任务(DONE或TIMEOUT-ed)之后,我尝试关闭执行程序,但它不会停止:exec.isTerminated() = FALSE.
我怀疑某些被执行的任务未正确终止.
是的,我知道执行者的关闭不能保证任何事情:
除尽力尝试停止处理主动执行任务之外,没有任何保证.例如,典型的实现将通过{@link Thread#interrupt}取消,因此任何未能响应中断的任务都可能永远不会终止.
我的问题是,有没有办法确保这些(任务)线程终止?我提出的最佳解决方案是System.exit()在程序结束时调用,但这很简单.
我有以下代码:
while(slowIterator.hasNext()) {
performLengthTask(slowIterator.next());
}
Run Code Online (Sandbox Code Playgroud)
因为迭代器和任务都很慢,所以将它们放入单独的线程是有意义的.以下是Iterator包装器的快速而脏的尝试:
class AsyncIterator<T> implements Iterator<T> {
private final BlockingQueue<T> queue = new ArrayBlockingQueue<T>(100);
private AsyncIterator(final Iterator<T> delegate) {
new Thread() {
@Override
public void run() {
while(delegate.hasNext()) {
queue.put(delegate.next()); // try/catch removed for brevity
}
}
}.start();
}
@Override
public boolean hasNext() {
return true;
}
@Override
public T next() {
return queue.take(); // try/catch removed for brevity
}
// ... remove() throws UnsupportedOperationException
}
Run Code Online (Sandbox Code Playgroud)
但是,这种实现缺乏对"hasNext()"的支持.当然可以阻止hasNext()方法阻塞,直到它知道是否返回true.我可以在我的AsyncIterator中有一个peek对象,我可以更改hasNext()从队列中获取一个对象并让next()返回此窥视.但是如果已达到委托迭代器的结尾,这将导致hasNext()无限期地阻塞.
我自己可以自己进行线程通信,而不是使用ArrayBlockingQueue:
private static class AsyncIterator<T> implements Iterator<T> {
private …Run Code Online (Sandbox Code Playgroud) 我想知道如何通知另一个线程的最佳方法。例如,我有一个后台线程:
public void StartBackgroundThread(){
new Thread(new Runnable() {
@Override
public void run() {
//Do something big...
//THEN HOW TO NOTIFY MAIN THREAD?
}
}).start();
}
Run Code Online (Sandbox Code Playgroud)
完成后必须通知主线程吗?如果有人知道最好的方法,我将不胜感激!
我有一个程序处理大量文件,每个文件需要完成两件事:首先,读取并处理文件的某些部分,然后MyFileData存储结果.第一部分可以并行化,第二部分不能.
按顺序执行所有操作都非常慢,因为CPU必须等待磁盘,然后它会工作一点,然后它会发出另一个请求,然后再次等待...
我做了以下
class MyCallable implements Callable<MyFileData> {
MyCallable(File file) {
this.file = file;
}
public MyFileData call() {
return someSlowOperation(file);
}
private final File file;
}
for (File f : files) futures.add(executorService.submit(new MyCallable(f)));
for (Future<MyFileData> f : futures) sequentialOperation(f.get());
Run Code Online (Sandbox Code Playgroud)
它帮助了很多.但是,我想改进两件事:
我正在尝试多生产者 - 生产者 - 消费者问题的多个消费者使用案例.我正在使用BlockingQueue在多个生产者/消费者之间共享公共队列.
以下是我的代码.
制片人
import java.util.concurrent.BlockingQueue;
public class Producer implements Runnable {
private BlockingQueue inputQueue;
private static volatile int i = 0;
private volatile boolean isRunning = true;
public Producer(BlockingQueue q){
this.inputQueue=q;
}
public synchronized void run() {
//produce messages
for(i=0; i<10; i++)
{
try {
inputQueue.put(new Integer(i));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Produced "+i);
}
finish();
}
public void finish() {
//you can also clear here if you wanted
isRunning = false;
} …Run Code Online (Sandbox Code Playgroud)