【发布时间】:2015-08-24 08:39:08
【问题描述】:
我面临一个问题,我必须处理许多试图在数据库中写入字符串列表的线程。为了清楚起见,让我们考虑 3 个线程正在访问 DB 的连接对象。所有线程都将具有字符串。让我们坐一下,线程 A 有一个名为“First”的字符串,线程 B 有“第二”,线程 C 有“第一”。假设下面是我想要保护的代码的关键部分,我将很快解释。
writeToDataBase(String stringFromEachThread);
线程 A 和线程 B 可以同时执行此方法,因为它们内部有不同的字符串值。当线程 A 从线程 C 执行时,我必须保护上面的代码,因为线程 C 也具有与线程 A 相同的字符串值。我需要让线程 C 等到线程 A 完成执行。所以我遇到了将线程放入队列的 java.util.Concurrent.Semaphore 类。但在我的情况下,只有线程 C 必须放入队列而不是线程 B。因为线程 B 具有唯一的字符串值,所以它可以与线程 A 并行执行。信号量在线程 A 执行时阻塞线程 C,但它也阻止线程 B。下面是代码 sn-p,我在其中使用信号量来实现这一点,到目前为止这还没有帮助。我已经解决这个问题一个多星期了。任何克服这个问题的建议都非常感谢。
Semaphore sm = new Semaphore(1, true);
... ...
public void lock(String str) throws InterruptedException {
if(!strAlreadExists()){
return;
}else{
sm.acquire();
}
}
【问题讨论】:
-
在我决定绝对需要信号量之前,我会考虑使用synchronized。这是关于“并发”、您拥有的选项以及这些选项之间的权衡的好教程:vogella.com/tutorials/JavaConcurrency/article.html
-
那是多少个字符串?此外,即使您同时执行它们,数据库也会序列化访问。那何必担心呢?
-
“数据库将序列化访问”--并非总是如此,这取决于隔离模式。
-
在您的代码方法中,
strAlreadExists()很可能不是原子的,if--else也不是原子的,因此整个lock()方法不同步,因此信号量无济于事。看看synchronized或java.util.concurrent.Lock -
@SashaSalauyou 他说的不是
serializable隔离模式。如果所有的写入都进入同一个表,那么无论隔离模式如何,它们都不能同时可靠地写入。
标签: java multithreading semaphore