【发布时间】:2019-06-06 16:12:56
【问题描述】:
我很清楚这可能被认为是重复的,但是考虑到我的问题,我在这里遇到了很多答案,我无法提出解决方案。
我将我的runnable与一个由多个线程共享的对象同步,并显式同步了我在里面使用的方法,但程序的结果总是3000。
我尝试锁定 Counter 类,但它不会改变任何事情。
谁能解释一下为什么我的操作在这个特定示例中不起作用?
public static void zad3() {
var counter = new Counter();
var toRun = new Runnable() {
@Override
public void run() {
synchronized (counter) {
for (var i = 0; i < 1000; i++) {
counter.add(1);
}
}
}
};
var t1 = new Thread(toRun);
var t2 = new Thread(toRun);
var t3 = new Thread(toRun);
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("counter = " + counter.getCount());
}
public class Counter {
protected long count_ = 0;
public synchronized void add(long value) {
count_ += value;
}
public long getCount() {
return count_;
}
}
编辑:
正如建议的那样,问题在于每个线程不断运行1000 次。
我的解决方案:
var toRun = new Runnable() {
@Override
public void run() {
synchronized (counter) {
for (var i = counter.getCount(); i < 1000; i++) {
counter.add(1);
}
}
}
};
【问题讨论】:
-
您期待什么结果?
-
@Jeppe 结果总是
3000,而我正在努力实现1000。 -
那么你应该限制循环在
counter.getCount() < 1000而不是i时运行。这意味着 2 个操作必须是原子的(读取,然后写入),(如果您删除循环周围的同步)。 -
如果你有 3 个线程,每个线程递增 1000 次,为什么你期望结果为 1000?
-
@Jeppe 是的,这很有意义。谢谢!
标签: java multithreading runnable executorservice