相关疑难解决方法(0)

为什么ThreadPoolExecutor将BlockingQueue作为其参数?

我尝试过创建和执行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 multithreading

19
推荐指数
2
解决办法
2万
查看次数

如何正确关闭java ExecutorService

我有一个简单的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()在程序结束时调用,但这很简单.

java multithreading shutdown executorservice

9
推荐指数
2
解决办法
8073
查看次数

异步迭代器

我有以下代码:

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)

java concurrency multithreading asynchronous

7
推荐指数
1
解决办法
3362
查看次数

如何通知另一个线程

我想知道如何通知另一个线程的最佳方法。例如,我有一个后台线程:

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)

完成后必须通知主线程吗?如果有人知道最好的方法,我将不胜感激!

java multithreading

6
推荐指数
1
解决办法
9412
查看次数

优化许多文件的并行处理

我有一个程序处理大量文件,每个文件需要完成两件事:首先,读取并处理文件的某些部分,然后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)

它帮助了很多.但是,我想改进两件事:

  • sequentialOperation获取固定的顺序,而不是处理任何结果,请首先执行.我该怎么改变它?

  • 有数千个文件需要处理,启动数千个磁盘请求可能导致磁盘丢失.通过使用Executors.newFixedThreadPool(10)我限制了这个数字,但我正在寻找更好的东西.理想情况下,它应该是自我调整的,以便它在不同的计算机上工作最佳(例如,当RAID和/或NCQ可用时发出更多请求等).我不认为它可以基于找出的硬件配置,但测量的处理速度,并在此基础上应该优化某种程度上是可能的.任何的想法?

java parallel-processing multithreading executorservice

3
推荐指数
1
解决办法
1036
查看次数

多生产者多消费者多线程Java

我正在尝试多生产者 - 生产者 - 消费者问题的多个消费者使用案例.我正在使用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)

java multithreading producer-consumer blockingqueue

2
推荐指数
2
解决办法
1万
查看次数