使用任何java.util.concurrent类时,是否仍需要在实例上同步访问以避免差异线程之间的可见性问题?
当使用java.util.concurrent的实例时,是否有可能一个线程修改实例(即,将一个元素放在一个并发的hashmap中),后续的线程将不会看到修改?
我的问题源于这样一个事实:如果对值的访问不同步,Java内存模型允许线程缓存值而不是直接从内存中获取它们.
java concurrency multithreading java.util.concurrent java-memory-model
我经常需要让一个线程等待另一个线程的结果.似乎在java.util.concurrent中应该有一些支持,但我找不到它.
交换器非常接近我所说的,但它是双向的.我只希望线程A在线程B上等待,而不是两个都在等待.
是的,我知道我可以使用CountDownLatch或Semaphore或Thread.wait()然后自己管理计算的结果,但似乎我必须在某个地方缺少一个便利类.
我错过了什么?
UPDATE
// An Example which works using Exchanger
// but you would think there would be uni-directional solution
protected Exchanger<Integer> exchanger = new Exchanger<Integer>();
public void threadA() {
// perform some computations
int result = ...;
exchanger.exchange(result);
}
public void threadB() {
// retrieve the result of threadA
int resultOfA = exchanger.exchange(null);
}
Run Code Online (Sandbox Code Playgroud) 我的代码抛出异常:
java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
at java.util.LinkedHashSet.<init>(LinkedHashSet.java:152)
...
Run Code Online (Sandbox Code Playgroud)
我想要ConcurrentLinkedHashSet修理它,
但我只找到ConcurrentSkipListSet了java.util.concurrent,这TreeSet不是LinkedHashSet
进入JDK6.0的任何简易方法ConcurrentLinkedHashSet?
感谢帮助 :)
我有一个多线程应用程序,它有一个生产者线程和几个消费者线程.数据存储在共享线程安全集合中,并在缓冲区中有足够数据时刷新到数据库.
来自javadocs -
BlockingQueue<E>
Run Code Online (Sandbox Code Playgroud)
一个队列,它还支持在检索元素时等待队列变为非空的操作,并在存储元素时等待队列中的空间可用.
take()
Run Code Online (Sandbox Code Playgroud)
检索并删除此队列的头部,必要时等待,直到元素可用.
我的问题 -
- 是否有另一个具有E [] take(int n)方法的集合?即阻塞队列等待直到元素可用.我想要的是它应该等到100或200个元素可用.
- 或者,是否有另一种方法可用于解决问题而无需轮询?
我正在研究java并发API并尝试理解读写锁的有用性.javadoc表示readwrite块维护一对锁,一个用于读取,另一个用于写操作.虽然写锁是线程的独占访问,但多个线程可以获取读锁.因此,如果在读取部分中我们所做的只是读取操作,并且我们无论如何都提供多线程访问,那么首先需要读取锁定是什么?是否存在readwrite锁实际有用的情况?
我需要为ThreadLocal最终运行特定CompletableFuture.supplyAsync供应商的所有线程提供一个。
从javadoc中,我看到CompletableFuture使用“ ForkJoinPool commonPool()”非常适合我的性能用例。
如何将ThreadLocal(然后删除)转移到运行特定CompletableFuture供应商的所有池线程?
备注:
我看到所有CompletableFuture async完成方法都接受执行程序。我想使用默认值,ForkJoinPool commonPool()但是如果无法实现,我想我必须重写ThreadPoolExecutor并实现beforeExecute吗?
在接受采访时被问到这个问题,试图解决它......但没有成功.我想过使用CyclicBarrier
有三个线程T1打印1,4,7 ... T2打印2,5,8 ...和T3打印3,6,9 .... 如何将这三个同步到打印顺序1,2,3,4,5,6,7,8,9 ....
我尝试编写并运行以下代码
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cBarrier = new CyclicBarrier(3);
new Thread(new ThreadOne(cBarrier,1,10,"One")).start();
new Thread(new ThreadOne(cBarrier,2,10,"Two")).start();
new Thread(new ThreadOne(cBarrier,3,10,"Three")).start();
}
}
class ThreadOne implements Runnable {
private CyclicBarrier cb;
private String name;
private int startCounter;
private int numOfPrints;
public ThreadOne(CyclicBarrier cb, int startCounter,int numOfPrints,String name) {
this.cb = cb;
this.startCounter=startCounter;
this.numOfPrints=numOfPrints;
this.name=name;
}
@Override
public void run() {
for(int counter=0;counter<numOfPrints;counter++)
{
try {
// System.out.println(">>"+name+"<< "+cb.await()); …Run Code Online (Sandbox Code Playgroud) 我们使用AtomicLongs收集一些统计信息。一些用户看到了关于这些的争执,并建议改用LongAdder。但是,正如我们目前使用Atomic所做的那样,我认为无法计算最大值:
AtomicLong _current, _total, _max;
...
void add(long delta)
{
long current = _current.addAndGet(delta);
if (delta>0)
{
_total.addAndGet(delta);
long max = _max.get();
while (current > max)
{
if (_max.compareAndSet(max, current))
break;
max = _max.get();
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我认为我们可以_total很容易地用替换掉LongAdder,但是因为这样做_current.addAndGet(delta)对a LongAdder来说效果不好,也不能对_max值进行cas操作。
是否有任何好的算法可以基于LongAdder或类似的可伸缩无锁构造收集此类统计信息?
实际上,尽管我要询问,但我们的统计信息通常会更新6至10个AtomicLongs。如果无论如何我们都在争论,那么仅仅抓住一个锁并更新6到10个正常的长仓可能会更好吗?
我的应用程序包含一个ListView每次选择项目时启动后台任务的应用程序.然后,后台任务在成功完成时更新UI上的信息.
但是,当用户快速点击一个又一个项目时,所有这些任务都会继续,最后一个任务将完成"获胜"并更新UI,无论最后选择了哪个项目.
我需要的是以某种方式确保此任务在任何给定时间只有一个实例运行,因此在开始新任务之前取消所有先前任务.
这是一个演示该问题的MCVE:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class taskRace extends Application {
private final ListView<String> listView = new ListView<>();
private final Label label = new Label("Nothing selected");
private String labelValue;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
// Simple UI
VBox root = new VBox(5);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
root.getChildren().addAll(listView, label);
// Populate the …Run Code Online (Sandbox Code Playgroud) 我正在使用ScheduledExecutorService并提交这样的任务:
future = scheduledExecutorService.schedule(myRunnableTask, delay, timeunit)
Run Code Online (Sandbox Code Playgroud)
但是,一定时间后可能会发生某个事件,这表明不再需要此任务。所以我需要取消此任务,而我正在使用
boolean cancelled = future.cancel(false) 线。
取消后,我必须根据提交的可运行对象是否实际运行来采取不同的操作。在这里,让我们首先进入Oracle文档并阅读cancelled标志的含义:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)
返回:如果无法取消任务(通常是因为它已经正常完成),则返回false;否则返回false。否则为真
这就是关于返回值的全部内容。似乎写此文本行的人false在这里不确定返回值,但我认为我可以接受。
现在,让我们集中讨论返回的情况true。这里有两种可能性:
我对这两种情况都可以,但是我想知道实际发生的一种并采取相应的措施。如果可运行对象正在处理中,那么我可以完成它的工作,我想等待它完成,然后做一件事。但是,如果它被取消并且根本不会运行,我想做另一件事。
您能推荐一种解决方法吗?我想念什么吗?