[英]Java concurrency using ConcurrentHashMap with synchronized block
Here is my main class that initializes and starts 5 different Threads:这是我的主类,它初始化并启动 5 个不同的线程:
public class Server implements Runnable {
Server1 server1;
Thread server1Thread;
public Server() {}
@Override
public void run() {
server1 = new Server1();
server1Thread = new Thread(server1);
server1Thread.start();
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
Server s = new Server();
s.run();
}
}
}
Here is my Server1
Runnable:这是我的
Server1
Runnable:
import java.util.concurrent.ConcurrentHashMap;
public class Server1 implements Runnable {
private ConcurrentHashMap<Integer, Integer> storage= new ConcurrentHashMap<>();
public Server1() {}
@Override
public void run() {
synchronized (this){
for (int i = 0; i < 10; i++) {
storage.put(i, (int)(Math.random()*100));
}
for (int i : storage.keySet()) {
System.out.print("(" + i + "," + storage.get(i) + ") ");
}
System.out.println();
}
}
}
It puts in ConcurrentHashMap storage
keys from 0
to 9
and assigns them a random value between 0
and 100
.它放入
ConcurrentHashMap storage
键从0
到9
并为它们分配一个0
到100
之间的随机值。 After that it prints it and prints new line at the end.之后它打印它并在最后打印新行。 I have user
synchronized
block to make sure the thread itself access keys correctly but it prints something like this:我有用户
synchronized
块以确保线程本身正确访问密钥,但它打印如下内容:
(0,8) (0,87) (1,60) (1,14) (2,20) (2,70) (3,5) (0,74) (0,42) (1,22) (4,96) (0,85) (1,97) (2,75) (3,68) (4,3) (5,49) (6,3) (7,9) (8,47) (9,52)
(3,2) (5,74) (2,86) (1,48) (3,5) (6,0) (4,0) (7,86) (4,22) (8,20) (2,17) (9,87)
(5,96) (5,15) (6,15) (6,92) (7,48) (8,93) (9,67)
(3,87) (7,43) (4,34) (5,48) (8,91) (9,64)
(6,84) (7,75) (8,47) (9,87)
which obviously means that some thread prints more that 10 keys that I assigned to it.这显然意味着某些线程打印了我分配给它的 10 个以上的键。 How do I make every thread print exactly 10 keys and values that it is assigned to them and ensure concurrency here?
如何让每个线程准确打印分配给它们的 10 个键和值并确保这里的并发性?
I am not sure how to test it.我不知道如何测试它。
Your threads don't share any internal state.您的线程不共享任何内部状态。 They're working fine, but the output is interleaved.
他们工作正常,但输出是交错的。
For instance if you used a StringBuilder
to do the I/O in one operation, you should see correct output.例如,如果您使用
StringBuilder
在一个操作中执行 I/O,您应该会看到正确的输出。
StringBuilder buff = new StringBuilder();
for (int i : storage.keySet()) {
buff.append("(" + i + "," + storage.get(i) + ") ");
}
System.out.println(buff);
There is no good reason for Server
to be Runnable
, or even to create any instances of it.没有充分的理由让
Server
成为Runnable
,甚至创建它的任何实例。
You do not share any of the maps.您不共享任何地图。 If you did, then you would also want to share a common lock, but this is not the usual way to use
ConcurrentMap
.如果您这样做了,那么您还希望共享一个公共锁,但这不是使用
ConcurrentMap
的常用方法。
All you had to do was synchronized (Server1.class)
as that is common across threads.您所要做的就是
synchronized (Server1.class)
因为这在线程间很常见。 Not the instance
不是
instance
Here is the verified output:这是经过验证的输出:
(0,75) (1,9) (2,61) (3,73) (4,55) (5,34) (6,34) (7,74) (8,41) (9,0)
(0,75) (1,9) (2,61) (3,73) (4,55) (5,34) (6,34) (7,74) (8,41) (9,0)
(0,30) (1,42) (2,46) (3,66) (4,12) (5,17) (6,62) (7,59) (8,74) (9,4)
(0,30) (1,42) (2,46) (3,66) (4,12) (5,17) (6,62) (7,59) (8,74) (9,4)
(0,50) (1,16) (2,29) (3,74) (4,68) (5,42) (6,33) (7,91) (8,25) (9,7)
(0,50) (1,16) (2,29) (3,74) (4,68) (5,42) (6,33) (7,91) (8,25) (9,7)
(0,49) (1,10) (2,39) (3,94) (4,12) (5,55) (6,54) (7,89) (8,21) (9,75)
(0,49) (1,10) (2,39) (3,94) (4,12) (5,55) (6,54) (7,89) (8,21) (9,75)
(0,77) (1,10) (2,37) (3,32) (4,73) (5,39) (6,64) (7,98) (8,96) (9,44)
(0,77) (1,10) (2,37) (3,32) (4,73) (5,39) (6,64) (7,98) (8,96) (9,44)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.