[英]Java Concurrency based on condition
创建一个接受整数作为参数的方法并在控制台上打印。 该方法由多个线程访问。 如果两个或多个线程使用相同的值调用该方法,则仅一个线程应允许打印该值,其他线程应等待。 如果值不同,则所有线程都应允许打印该值。 我知道interning在这里会有所帮助,但是Java进行intern直到值小于128。之后,两个具有相同值的Integer是不同的对象...可以这样做吗? 有条件同步的任何规定吗?
关于防止多个线程打印相同值,但允许它们打印不同线程的要求
防止这种情况的最简单方法是已经打印了一组整数。 由于要打印,使用锁的开销很小。
Set<Integer> printed = Collections.synchronizedSet(new HashSet<Integer>());
// when printing
if (printed.add(num)) // will one be true the first time for each number
System.out.println("num: " + num);
能做到吗
打印到控制台已经同步,无论您做什么,所有线程都将同步其打印,无论您做什么。 添加更多锁定不会改变这一点。
例如从实现System.out和err的PrintStream中
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
您不能简单地决定忽略来自调用方的synchronized
。
有条件同步的任何规定吗?
最简单的操作是锁定不同的锁或本地线程。 锁定不满意的对象非常快。
例如
synchronized(shared ? sharedObject : Thread.currentThread()) {
}
顺便说一句,这是一件非常奇怪/令人困惑的事情。 我会认真考虑更改您的设计,因此这不是必需的。 编写普通的多线程代码很难编写/理解。
private static final Set<Integer> lockedIntegers = new HashSet<>();
private void lock(Integer key) throws InterruptedException {
synchronized (lockedIntegers) {
while (!lockedIntegers.add(key)) {
lockedIntegers.wait();
}
}
}
private void unlock(Integer key) {
synchronized (lockedIntegers) {
lockedIntegers.remove(key);
lockedIntegers.notifyAll();
}
}
public void printEqualIntegersSynchronously(Integer key) throws InterruptedException {
try {
lock(key);
System.out.println(key);
//Do whatever you need with your key.
//For different keys this part is executed in parallel.
//For equal keys this part is executed synchronously.
} finally {
unlock(key);
}
}
最后尝试 -非常重要-即使操作引发异常,您也必须保证在操作后解锁等待线程。 'System.out.println'很可能永远不会抛出异常-但是在其他实际情况下,“最终尝试”是强制性的。 顺便说一下,“ System.out.println”已经被自己同步了,所以对于“ System.out.println”来说就不需要了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.