我有一个Callable<String>.我想定期运行它ScheduledExecutorService.scheduleAtFixedRate(),并获取.call()我的callable上的调用返回的所有字符串的列表.由于scheduleAtFixedRate不采取 Callable(只有Runnables)我需要推出一个自定义Runnable包装我的Callable东西,沿着这些方向:
final Callable<String> myCallable = ....;
final ConcurrentLinkedQueue<String> results
= new ConcurrentLinkedQueue<String>();
Runnable r = new Runnable() {
@Override public void run() {
try {
results.add(myCallable.call());
} catch (Exception e) {
results.add(null); // Assuming I want to know that an invocation failed
}
}
};
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(r, 0, 1, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
当然,我想避免推出我自己的自定义东西(特别是在多线程代码中),所以我想知道有一个JDK类可以进行这种聚合吗?
我正在浏览java.util.concurrent.atomic.AtomicInteger的源代码,以了解如何通过类提供的原子操作实现原子性.例如AtomicInteger.getAndIncrement()方法源如下
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
Run Code Online (Sandbox Code Playgroud)
我无法理解在无限for循环中编写操作序列的目的.它在Java Memory Model(JMM)中是否有任何特殊用途.请帮我找一个描述性的理解.提前致谢.
我的程序通过分而治之的方法搜索问题的解决方案(任何解决方案),使用递归和实现RecursiveTasks:我为该部门的第一个分支派一个任务,然后递归到第二个分支:如果第二个分支找到了解决方案,然后我取消了第一个分支,否则我等待它的结果.
这可能不是最佳的.如果找到解决方案,一种方法是针对任何已启动的任务抛出异常.但是,我将如何取消所有已启动的任务?取消任务是否也取消所有子任务?
来自java docs,
ForkJoinPool与其他类型的ExecutorService的不同之处主要在于使用工作窃取:池中的所有线程都尝试查找和执行由其他活动任务创建的子任务(如果不存在则最终阻塞等待工作).
这可以在大多数任务产生其他子任务时实现高效处理(与大多数ForkJoinTasks一样).在构造函数中将asyncMode设置为true时,ForkJoinPools也可能适用于从未加入的事件样式任务.
通过下面的ForkJoinPool示例,与ThreadPoolExecutor不同,我没有看到设置队列大小的参数.我没有弄清楚ForkJoinPool如何窃取机制.
//creating the ThreadPoolExecutor
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 10, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(3000), threadFactory, rejectionHandler);
Run Code Online (Sandbox Code Playgroud)
假设我已经创建了具有10个线程的ThreadPoolExecutor,并且已经提交了3000个Callable任务.这些线程如何共享子任务的执行负载?
并且ForkJoin池如何针对相同的用例表现不同?
java multithreading java.util.concurrent threadpoolexecutor forkjoinpool
我想为工作窃取池使用的ForkJoinPool的线程设置名称,由.提供
ExecutorService newWorkStealingPool(int parallelism)
Run Code Online (Sandbox Code Playgroud)
要么
ExecutorService newWorkStealingPool()
Run Code Online (Sandbox Code Playgroud)
到目前为止,我找不到在这个线程上设置自定义名称ExecutorService的方法,有没有办法?
newWorkStealingPool()基本上提供了一个ForkJoinPool,但ForkJoinPool也没有提供名称模式的公共构造函数.
更新:我现在发现这个构造函数
ForkJoinPool需要一个线程工厂ForkJoinPool.ForkJoinWorkerThreadFactory.但是工厂应该返回a ForkJoinWorkerThread,它没有公共构造函数.所以我想我必须继承ForkJoinWorkerThread.
我有一个类似这样的程序
public class Test implements Runnable
{
public int local_counter
public static int global_counter
// Barrier waits for as many threads as we launch + main thread
public static CyclicBarrier thread_barrier = new CyclicBarrier (n_threads + 1);
/* Constructors etc. */
public void run()
{
for (int i=0; i<100; i++)
{
thread_barrier.await();
local_counter = 0;
for(int j=0 ; j = 20 ; j++)
local_counter++;
thread_barrier.await();
}
}
public void main()
{
/* Create and launch some threads, stored on thread_array …Run Code Online (Sandbox Code Playgroud) java parallel-processing concurrency synchronization java.util.concurrent
好吧,标题基本上说明了一切,还有我真的很想知道何时使用它们的少量补充。可能很简单-我已经阅读了它们的文档,但仍然不能说出太多区别。
有喜欢回答这个位置,基本上说:
屈服对于忙碌的等待也很有用...
我不太同意他们的说法,原因很简单,即内部ForkJoinPool使用Thread::yield,这是jdk世界中的新增功能。
真正困扰我的是jdk中的用法(StampledLock::tryDecReaderOverflow):
else if ((LockSupport.nextSecondarySeed() & OVERFLOW_YIELD_RATE) == 0)
Thread.yield();
else
Thread.onSpinWait();
return 0L;
Run Code Online (Sandbox Code Playgroud)
因此,似乎在某些情况下,一个会比另一个更受欢迎。而且,没有,我没有实际的示例可能需要使用它-我实际使用的唯一示例是Thread::onSpinWait因为1)我碰巧忙于等待2)这个名字很能说明我应该在忙碌中使用它旋转。
从Javadoc我知道ConcurrentHashMap.replace是原子的,但是怎么样ConcurrentHashMap.put?我看到它们在源代码中的实现方式不同,但我无法弄清楚它们的区别.任何大师都会给出一些关于如何使用这两种方法的指导方针?
假设我需要处理3种类型的请求:A,B和C,如下所示:
更一般地,类型的数量是N并且并发请求的数量是K <= N.
你将如何在Java中实现它java.util.concurrent?
我有一个ThreadPoolExecutor,我向它提交任务.
private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
Run Code Online (Sandbox Code Playgroud)
此代码提交Runnable给ThreadPoolExecutor.
protected void waitAndSweep(final String symbol) {
runnable = new Runnable() {
public void run() { /* irrelevant code */ }
};
try {
Future<?> self = threadPoolExecutor.submit(runnable);
futures.add(self);
} catch (RejectedExecutionException re) {
/* this exception will be thrown when wait and sweep is called more than twice.
* threadPoolExecutor can have one running task and one waiting task.
*/
} …Run Code Online (Sandbox Code Playgroud)