嘿SO Guru,我对这段代码有一点工作
public void kill(double GrowthRate, int Death)
{
int before = population.size();
for (PopulationMember p : population)
{
int[] probs = ProbablityArrayDeath(GrowthRate,Death,(int)p.fitness());
if (probs[RandomNumberGen.nextRandomInt(0, 99)]==0)
{
population.remove(p);
}
}
System.out.println("Intial Population: "+before+", Deaths:"+(before- population.size())+", New Population: "+population.size());
}
Run Code Online (Sandbox Code Playgroud)
当我第一次尝试运行代码时运行我的程序时,它会遇到此错误
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
at java.util.HashMap$KeyIterator.next(HashMap.java:828)
at Genetics.Population.kill(Population.java:181)
at Genetics.Population.run(Population.java:47)
at Control.Main.main(Main.java:35)
Run Code Online (Sandbox Code Playgroud)
稍微晃了一下这似乎是一个错误,通常会发生在线程为什么他们尝试同时访问相同的资源,但这就是让我在这个系统中完全没有多线程的原因.
有人可以解释为什么会这样,或者想到一个黑客来解决它
非常感谢^ _ ^
我想知道ConcurrentHashMap如何处理rehashing而另一个线程仍然在另一个段/分区上写.据我所知,ConcurrentHashMap独立地锁定了段,因此,例如,Thread1在Thread2写入segment2之前稍微写入segment1,如果它要求表在Thread1插入后调整大小并重新散列,会发生什么,但是Thread2位于中间写作操作?它会锁定整个地图以进行重组吗?它是否有类似告诉Thread2停止并等到rehash完成?因为Thread2可能有机会在表调整大小后最终写出segment1,对吗?
CyclicBarrier/ CountDownLatch和joinJava 之间的区别是什么?有什么优势CyclicBarrier和CountDownLatch?在我看来,只需使用join我们就可以等待一个线程完成它的执行.
我可以在没有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 …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading executorservice java.util.concurrent
一个线程死锁饥饿如果池中的所有线程都在等待同一个池中排队的任务完成发生在一个正常的线程池. ForkJoinPool通过从join()调用内部窃取其他线程的工作来避免这个问题,而不是简单地等待.例如:
private static class ForkableTask extends RecursiveTask<Integer> {
private final CyclicBarrier barrier;
ForkableTask(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
protected Integer compute() {
try {
barrier.await();
return 1;
} catch (InterruptedException | BrokenBarrierException e) {
throw new RuntimeException(e);
}
}
}
@Test
public void testForkJoinPool() throws Exception {
final int parallelism = 4;
final ForkJoinPool pool = new ForkJoinPool(parallelism);
final CyclicBarrier barrier = new CyclicBarrier(parallelism);
final List<ForkableTask> forkableTasks = new ArrayList<>(parallelism);
for (int …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading java.util.concurrent fork-join
Thread 1: Call list.add()
Thread 1: Exits list.add()
Thread 2: Call list.get(list.size()-1)
Run Code Online (Sandbox Code Playgroud)
我有一个场景,我可以保证Thread 1在进行Thread 2get()调用之前完成add ()调用.将Thread 2始终看到所做的更改Thread 1在这种情况下?或者内部ArrayList变量是否需要标记为volatile?
编辑:对于那些对我能保证的原因感到好奇的人.我有一系列来自服务器的事件,如下所示:
Event A1
Event A2
Event A3
Event B
Run Code Online (Sandbox Code Playgroud)
事件由单个线程按顺序分派.我想捕获所有A事件的列表,所以我的代码看起来像这样:
List<EventA> eventAList = new ArrayList<>();
connection.addListenerForEventAs(eventAList::add);
connection.waitForEventB();
//Here I am doing operations on the eventAList
Run Code Online (Sandbox Code Playgroud) Java 8引入了获取并发Set实现的新方法
// Pre-Java-8 way to create a concurrent set
Set<String> oldStyle = Collections.newSetFromMap(new ConcurrentHashMap<>());
// New method in Java 8
Set<String> newStyle = ConcurrentHashMap.newKeySet();
Run Code Online (Sandbox Code Playgroud)
有什么理由喜欢新方法吗?
有什么优点/缺点?
我试图找到指示java.util.concurrent.Future是否是线程安全的文档.例如,我可以安全地将Future的相同实例提供给多个线程,这些线程都会调用Future.get(...)吗?
我已经用这种方式使用Future测试了代码,它似乎工作得很好,但如果我能找到记录的期望,以这种方式未来对于并发访问是安全的,我会更高兴.
谢谢.
这对于今天另一个问题的回答是一个"副作用" .这更多是关于好奇心而不是实际问题.
Java SE 7提供了Oracle称之为"fork/join框架"的东西.这是将工作安排到多个处理器的一种可能的优秀方式.虽然我理解它应该如何工作,但我无法理解它优越的地方和关于偷工作的说法.
也许其他人更深入地了解为什么这种方法是可取的(除了因为它有一个奇特的名字).
/加盟叉的根本原语ForkJoinTasks,这是FutureS,而这个想法是要么执行工作立即[原文](措辞是误导,因为"立即"意味着它同步发生在主线程,在现实中发生这种情况的内部a Future)低于某个阈值或递归地将工作划分为两个任务,直到达到阈值.
未来是一种封装任务的概念,该任务以不透明和未指定的方式异步运行到对象中.您有一个函数可以验证结果是否可用,并且您获得了一个允许您(等待和)检索结果的函数.
严格地说,你甚至不知道未来是否异步运行,它可以在内部执行get().从理论上讲,实现可以为每个未来生成一个线程或使用线程池.
实际上,Java将future作为任务队列上的任务实现,并附加了一个线程池(对于整个fork/join框架也是如此).
fork/join文档给出了这个具体的用法示例:
protected void compute() {
if (mLength < sThreshold) {
computeDirectly();
return;
}
int split = mLength / 2;
invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
}
Run Code Online (Sandbox Code Playgroud)
这将以与Mergesort将如何遍历它们的方式相同的方式将任务提交给底层线程池的任务队列(由于递归).
比如说我们有一个32个"项目"的数组要处理并且阈值为4,并且均匀分割,它将产生8个任务,每个具有4个"项目",看起来像这样:
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading java.util.concurrent fork-join
我对以下内容感到困惑
我知道,如果我使用该类中的schedule方法ScheduledThreadPoolExecutor:
ScheduledFuture<?> scheduledFuture =
scheduledThreadPoolExecutor.schedule(myClassRunnable, 5, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
我能够通过或稍后检索值,
并且应该为null,因为该任务只执行了一次并且已完成.并且null因为我正在使用方法版本而不是方法版本.它符合APIscheduledFuture.get(5, TimeUnit.SECONDS)scheduledFuture.get()shedule's Runnableshedule's Callable
直到这里我很好.
我的问题:
ScheduledFuture从scheduleWithFixedDelay(甚至来自scheduleAtFixedRate)方法中检索if 的目的是什么:
ScheduledFuture<?> scheduledFuture=
scheduledThreadPoolExecutor.scheduleWithFixedDelay(myClassRunnable, 1, 5, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
是的,我知道两种固定方法多次执行相同的任务,直到ScheduledThreadPoolExecutor's shutdown调用该方法(它必须停止所有已安排的任务).
我做了一项研究,通过谷歌寻找一些使用ScheduledFuture返回的例子scheduleWithFixedDelay,我只找到一个使用cancel方法,取消一个特定的任务.但没有人与get合作.
我不知道我是不是错了,但如果我们正在使用,似乎没有get方法scheduleWithFixedDelay,因为如果我以后使用:
我以为我应该能够检索空值,因为我可以使用方法中的period参数/参数scheduleWithFixedDelay.我的意思是:运行Runnable对象,等待它完成并使用scheduledFuture.get()获取确认它已完成的空值,等待延迟时间的周期再次运行Runnable对象根据period值等....
澄清和例子非常受欢迎
提前致谢.