英文:
Is there a need to use synchronized when using Concurrent APIs
问题
在使用并发API时是否需要使用synchronized
?换句话说,这三种方式之间有区别吗?
class MessageQueue {
Queue<String> q = new LinkedList<>();
public void post(String msg) {
synchronized (q) {
q.add(msg);
}
}
public String get() {
synchronized (q) {
return q.poll();
}
}
}
class MessageQueue2 {
Queue<String> q = new ConcurrentLinkedQueue<>();
public void post(String msg) {
q.add(msg);
}
public String get() {
return q.poll();
}
}
class MessageQueue3 {
Queue<String> q = new ConcurrentLinkedQueue<>();
public void post(String msg) {
synchronized (q) {
q.add(msg);
}
}
public String get() {
synchronized (q) {
return q.poll();
}
}
}
英文:
Is there a need to use synchronized
when working with Concurrent APIs? In other words is there a difference between this
class MessageQueue {
Queue<String> q = new LinkedList<>();
public void post(String msg) {
synchronized (q) {
q.add(msg);
}
}
public String get() {
synchronized (q) {
return q.poll();
}
}
}
this,
class MessageQueue2 {
Queue<String> q = new ConcurrentLinkedQueue<>();
public void post(String msg) {
q.add(msg);
}
public String get() {
return q.poll();
}
}
and this ?
class MessageQueue3 {
Queue<String> q = new ConcurrentLinkedQueue<>();
public void post(String msg) {
synchronized (q) {
q.add(msg);
}
}
public String get() {
synchronized (q) {
return q.poll();
}
}
}
答案1
得分: 1
并发容器可以安全地在多个线程中使用。这意味着修改容器的操作会进行同步,即多个线程修改容器不会使其损坏。因此,对于这种特定用法,#1和#2在功能上是等效的,而#3使用了冗余的同步。
这并不意味着你可以使用并发容器实现任何算法并去除同步。
如果算法涉及多个共享对象或对同一对象的多个操作,则需要一个同步块来包含所有操作,即使你使用了并发容器。如果没有包含同步块,其他线程可能会并发运行并创建竞争条件,即使容器是线程安全的。
英文:
Concurrent containers are safe to use from multiple threads. That means operations that modify the container take care of synchronization, i.e. multiple threads modifying the container will not corrupt it. So for this particular usage, #1 and #2 are functionally equivalent, and #3 uses redundant synchronization.
That doesn't mean you can implement any algorithm using a concurrent container and remove synchronization.
If the algorithm involves multiple shared objects or more than one operation on the same object, then you need a synchronized block to enclose all operations even if you use a concurrent container. Without an enclosing synchronized block, other threads may run concurrently and create a race condition, even if the containers are thread-safe.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论