[英]looking for java concurrency model suggestion
我正在使用AMQP将多个线程排队进行图搜索。 除非通过单独的线程按固定间隔进行修改,否则该图不会被修改。 什么是最好的并发模型来等待所有活动搜索完成,阻止那些线程并允许更新线程在取消阻止搜索线程之前修改图形?
我一直在阅读http://docs.oracle.com/javase/tutorial/essential/concurrency/,但似乎找不到与我的模型完全相符的内容。
有什么建议么?
谢谢!
编辑:我正在使用ExecutorService处理线程。
您真的需要阻止吗? 也许无阻塞的写时复制就足够了。
更新线程应制作一个当前图形结构的副本,并在该副本上应用更新。 完成更新后,应宣布新图形-只是覆盖共享引用。
搜索线程应将图形引用保存到局部变量或范围一次并使用它。 共享图永远不会被修改,因此不需要任何锁定和等待。
优点:
缺点:
也可以仅将写时复制应用于图的一部分。 尤其是当图形是内存消耗结构时。 但是,这是一个很难的话题-请参阅MVCC和STM(软件事务存储) 。
我不熟悉AMQP,但这是生产者/消费者问题,因此有几种方法可以用Java处理。 这是使用Futures和ReentrantLock的一个非常快速而肮脏的示例:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo {
private static Random rand = new Random();
private static final Lock lock = new ReentrantLock();
private static boolean updating = false;
private static List<Future<Integer>> futureList = new ArrayList<Future<Integer>>();
private static ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() {
return rand.nextInt();
}
};
private static void doUpdate() {
if (lock.tryLock()) {
updating = true;
try {
for (Future<Integer> future : futureList) {
System.out.println(future.get());
}
futureList.clear();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println();
lock.unlock();
updating = false;
}
}
}
public static void main(String[] args) throws Exception {
// submitter thread
new Thread(new Runnable() {
@Override
public void run() {
int submitCount = 0;
while (submitCount < 10) {
if (!updating) {
futureList.add(pool.submit(callable));
submitCount++;
}
try {
Thread.sleep(1000); // arbitrary
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// update thread
new Thread(new Runnable() {
@Override
public void run() {
int updateCount = 0;
while (updateCount < 5) {
doUpdate();
updateCount++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
我将更新线程设置为提交线程频率的一半。 因此,如果运行此更新程序,则每次运行时都会看到更新程序剥离两个整数。 提交线程必须等待,直到更新程序释放锁。
还有其他方法-查看BlockingQueue接口:您可能想尝试一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.