Java 多对象和计数器的同步
我知道很多人在这个话题上有问题,你可能会觉得无聊,但我从几天开始就试图理解它,但仍然不知道它是如何工作的:(.我有一个计数器对象,还有另一个类的其他对象(将来不止一个类).现在每个对象都应该响应计数器执行。一个计数-每个对象运行方法的一个步骤。这是我的代码:Java 多对象和计数器的同步,java,synchronization,counter,synchronized,Java,Synchronization,Counter,Synchronized,我知道很多人在这个话题上有问题,你可能会觉得无聊,但我从几天开始就试图理解它,但仍然不知道它是如何工作的:(.我有一个计数器对象,还有另一个类的其他对象(将来不止一个类).现在每个对象都应该响应计数器执行。一个计数-每个对象运行方法的一个步骤。这是我的代码: public class Th { private final static Object lock1 = new Object(); ////////////////////////////////////////////////
public class Th {
private final static Object lock1 = new Object();
////////////////////////////////////////////////////////////////////////////////
private class Stop implements Runnable {
private int count, id;
public Stop(int id) {
this.count = 0;
this.id = id;
}
@Override public void run() {
synchronized(lock1){
while (count < 20) {
try {
lock1.wait();
}
catch (InterruptedException exception) {
System.out.println("Error!");
}
System.out.println(count + " stop " + id);
this.count++;
// try {
// Thread.sleep(360);
// }
// catch (InterruptedException exception) {
// System.out.println("Error!");
// }
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
private class Counter implements Runnable {
private int count;
public Counter() {
this.count = 0;
}
@Override public void run() {
synchronized(lock1){
while (count<15) {
lock1.notifyAll();
System.out.println(count + " counter");
this.count++;
// try {
// Thread.sleep(360);
// }
// catch (InterruptedException exception) {
// System.out.println("Error!");
// }
}
}
}
}
public void test() {
Stop s1 = new Stop(1);
Stop s2 = new Stop(2);
Stop s3 = new Stop(3);
Counter counter = new Counter();
(new Thread(s1)).start();
(new Thread(s2)).start();
(new Thread(counter)).start();
(new Thread(s3)).start();
}
}
我需要的是:
0 counter
0 stop 0
0 stop 1
0 stop 2
1 counter
1 stop 0
1 stop 1
1 stop 2
2 counter
2 stop 0
2 stop 1
2 stop 2
3 counter
...
计数器
线程的整个循环在lock1
上同步。这意味着,尽管在此循环中调用notifyAll
,但在整个循环在计数器
线程中结束之前,其他线程无法重新获得锁
使循环的每个迭代同步,而不是在循环外同步
但请注意,这还不够,因为计数器线程可能在所有停止线程重新获取锁之前重新获取锁。您需要让计数器线程在另一个条件下等待,并在所有停止线程都显示计数后使其重新启动
您应该研究更高级别的抽象,如CyclicBarrier和CountDownLatch。首先,解决这个问题的最佳方法是使用更高级别的同步类,正如JB Nizet所说 但是,如果您想以“艰难的方式”进行学习,您需要认识到这个问题需要计数器和停止线程等待特定的“事件”
- 停止线程需要等待,直到计数器线程告诉它们前进到下一个停止
- 计数器线程需要等待,直到所有停止线程都已前进并停止
当前实现的一个问题是,当所有停止线程都已前进并停止时,计数器线程无法告诉它。相反,它假定当它看到notify事件时,可以发出下一个计数。我尝试了这个方法,但它没有解决问题(或者说解决了问题的一部分:)。这是一个输出:
0计数器0停止1计数器2计数器3计数器4计数器0停止2 1停止1 5计数器2停止1 6计数器7计数器8计数器9计数器10计数器11计数器12计数器13计数器14计数器1停止2 3停止1
读取我答案的第二部分
0 counter
0 stop 0
0 stop 1
0 stop 2
1 counter
1 stop 0
1 stop 1
1 stop 2
2 counter
2 stop 0
2 stop 1
2 stop 2
3 counter
...