如何解决为什么这些同步方法不断为我提供不同的输出?
我需要可以访问同一数据的线程同时执行,而又不会互相干扰,所以我一直在尝试使用同步方法,而不是使用Thread.join()
。问题是我什么都看不到,它给了我与使用它们之前相同的结果。我什至不知道我到底在做什么错,同步
方法假设可以阻止其他同步方法在完成之前执行,对吗?希望你能给我一些线索。
public class ThreadSync{
public static void main(String[] args) throws InterruptedException {
//if execute properly
//output can't be other than 0
while(true) {
ChangeValue counter = new ChangeValue();
Threads t = new Threads(counter,"up");
Threads t2 = new Threads(counter,"down");
Threads t3 = new Threads(counter,"print");
t.start();
t2.start();
t3.start();
}
}
}
class Threads extends Thread{
Threads(ChangeValue obj,String act){
counter = obj;
action = act;
}
@Override
public void run() {
switch(action) {
case ("up"): counter.up(); break;
case ("down"): counter.down(); break;
case ("print"): counter.print(); break;
}
}
ChangeValue counter;
String action;
}
class ChangeValue{
public synchronized void up() { value++; }
public synchronized void down() { value--; }
public synchronized void print() { System.out.println(value); }
public int value = 0;
}
解决方法
同步仅确保方法不会同时执行。但是,它不能保证任何执行顺序。
您需要确保在其他线程终止之前不执行print()
。这可以通过连接线程来实现。为此,执行
t.join();
t2.join();
在启动打印线程之前或在执行其逻辑之前。
请注意,同步仍然是明智的,因为它确保自动执行增量和减量操作。也就是说,在执行count
时读取,递增和写入count++
会立即执行
(另请参见:Why is i++ not atomic?)。因此,它阻止了以下执行顺序:
- [线程“向上”]:将值
count
加载到0
- [线程“关闭”]:将值
count
加载到0
- [线程“向上”]:将
count
增至1
- [线程“向下”]:将
count
减为-1
- [线程“向上”]:将
count
存储到值1
- [线程“关闭”]:将
count
存储到值-1
(这是数据库术语中的“丢失的更新”。)
, synchronized
使您的线程无法同时访问该字段,但当然不能保证线程执行的顺序。
例如,如果偶然地首先执行“ Up”线程,然后执行“ Print”线程,最后执行“ Down”线程,则即使所有线程完成后计数器值为0,输出也将为1。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。