Java 如何使此代码更并发?

Java 如何使此代码更并发?,java,multithreading,concurrency,threadpool,java.util.concurrent,Java,Multithreading,Concurrency,Threadpool,Java.util.concurrent,我有一段代码类似于以下内容: final int THREADS = 11; BlockingQueue<Future<Long>> futureQueue = new ArrayBlockingQueue<Future<Long>>(THREADS); for (int i = 0; i < end; i++, count++) { futureQueue.put(executor.submit(MyRunnable))

我有一段代码类似于以下内容:

final int THREADS = 11;  
BlockingQueue<Future<Long>> futureQueue = new ArrayBlockingQueue<Future<Long>>(THREADS);  
for (int i = 0; i < end; i++, count++) {  
    futureQueue.put(executor.submit(MyRunnable));  
}   
//Use queued results
final int THREADS=11;
BlockingQueue futureQueue=新阵列BlockingQueue(线程);
对于(int i=0;i
我如何重构它以使其更并发?我在这里监督的有什么微妙之处吗

更新:
每个Runnable都应该向服务器发送大量HTTP请求以进行压力测试。我的思路正确吗?

我会使用

static final int THREADS = Runnable.getRuntime().availableProcesses();  

ExecutorService service = Executors.newFixedThreadPool(THREADS);

List<Future<Long>> futureQueue = new ArrayList<Future<Long>>(end);  
for (int i = 0; i < end; i++)
    futureQueue.add(executor.submit(new MyRunnable()));  
如果有1000多个线程,那么使用NIO可能会有好处,但这只会使负载测试仪更高效,但会使代码更复杂。(如果您认为这很难,那么编写高效、正确的选择器代码就难多了)

在多台机器上运行测试仪会产生更大的差异。

我会使用

static final int THREADS = Runnable.getRuntime().availableProcesses();  

ExecutorService service = Executors.newFixedThreadPool(THREADS);

List<Future<Long>> futureQueue = new ArrayList<Future<Long>>(end);  
for (int i = 0; i < end; i++)
    futureQueue.add(executor.submit(new MyRunnable()));  
如果有1000多个线程,那么使用NIO可能会有好处,但这只会使负载测试仪更高效,但会使代码更复杂。(如果您认为这很难,那么编写高效、正确的选择器代码就难多了)


在多台机器上运行测试仪将产生更大的差异。

在您的情况下,使用线程不起作用。当您有CPU密集型作业时,线程池工作良好。在您的情况下,您有一个IO密集型作业—它不受您拥有的CPU数量的限制,而是受您可以发送的网络数据包数量的限制

在本例中,NIO中的类是您的朋友。创建数百个连接并使用以查看哪一个已准备好接收更多数据

使用这种方法,您根本不需要线程;一个CPU核心足以填满一个GBit以太网连接(~100MB/s)

[编辑]当然,您可以创建数百个线程来尝试填充IO通道。但这也有一些缺点:

  • 线程由操作系统(或小型助手库)管理。它们需要内存,每次切换线程时,CPU都必须保存其状态并刷新其缓存
  • 如果一个线程只做少量的工作,那么线程切换可能比执行工作更昂贵
  • 使用线程时,会遇到所有常见的线程同步问题
  • 没有简单的方法可以确保线程数量正确。如果线程太少,IO通道将无法得到最佳使用。如果有太多的线程,通道将不会得到最佳使用,因为线程将争夺对它的访问权。在这两种情况下,您都无法在开始测试后更改此设置。这个系统不适应需要

  • 对于这样的任务,像这样的框架更适合,因为它避免了所有这些问题,而且比线程更易于使用。

    在您的情况下,使用线程并不好。当您有CPU密集型作业时,线程池工作良好。在您的情况下,您有一个IO密集型作业—它不受您拥有的CPU数量的限制,而是受您可以发送的网络数据包数量的限制

    在本例中,NIO中的类是您的朋友。创建数百个连接并使用以查看哪一个已准备好接收更多数据

    使用这种方法,您根本不需要线程;一个CPU核心足以填满一个GBit以太网连接(~100MB/s)

    [编辑]当然,您可以创建数百个线程来尝试填充IO通道。但这也有一些缺点:

  • 线程由操作系统(或小型助手库)管理。它们需要内存,每次切换线程时,CPU都必须保存其状态并刷新其缓存
  • 如果一个线程只做少量的工作,那么线程切换可能比执行工作更昂贵
  • 使用线程时,会遇到所有常见的线程同步问题
  • 没有简单的方法可以确保线程数量正确。如果线程太少,IO通道将无法得到最佳使用。如果有太多的线程,通道将不会得到最佳使用,因为线程将争夺对它的访问权。在这两种情况下,您都无法在开始测试后更改此设置。这个系统不适应需要

  • 对于这样的任务,像这样的框架更适合,因为它避免了所有这些问题,并且比线程更易于使用。

    end
    线程
    大得多。也许我应该提到这一点,但这个(每个
    可运行的
    )应该向服务器发送大量HTTP请求以进行压力测试。我走对了吗?你说的
    如果结束>线程它将停止是什么意思。
    ?@Jim我是说你特别选择了一个容量有限的集合,您选择了
    put
    方法,该方法在阻塞队列已满时进行阻塞。因此,如果您的任务超过了您的容量,队列将被填满,它将被阻塞。@PeterLawrey:那么,如果我更改为
    add
    是否可以?
    add
    将在队列已满时放弃未来。
    end
    THREADS
    大得多。也许我应该提到这一点,但这个(每个
    可运行的
    )应该向服务器发送大量HTTP请求以进行压力测试。我走对了吗?你说的
    如果结束>线程它将停止是什么意思。
    ?@Jim我是说你特别选择了一个容量有限的集合,您选择了
    put
    方法,该方法在阻塞队列已满时进行阻塞。因此,如果您的任务多于您的产能,队列将被填满,它将被阻塞。@PeterLawrey:那么,如果我更改为
    add
    是否可以?
    add
    将在队列满时放弃未来。“仅当您有CPU密集型作业时使用线程才有帮助”-这不是真的。IO b