我需要有权访问相同数据的线程同时执行,而不会相互干扰,因此使用 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;
}
2条答案
按热度按时间x4shl7ld1#
同步只是确保方法不会同时执行。但是,它并不保证任何执行命令。
你需要确保
print()
在其他线程终止之前不执行。这可以通过连接螺纹来实现。为此,请执行在启动打印线程或执行其逻辑之前。
请注意,同步仍然是合理的,因为它确保增量和减量操作以原子方式执行。也就是说,读,加,写
count
执行时count++
立即执行(另请参阅:为什么i++不是原子的?)。从而防止以下执行顺序:[线程“向上”]:加载
count
有价值的0
[线程“向下”]:加载count
有价值的0
[线程“向上”]:增量count
至1
[线程“向下”]:递减count
至-1
[线程“向上”]:存储count
有价值的1
[线程“向下”]:存储count
有价值的-1
(这是数据库术语中的“丢失更新”。)a1o7rhls2#
synchronized
防止线程同时访问字段,但是当然它不能保证线程的执行顺序。例如,如果“up”线程首先执行,“print”线程第二次执行,“down”线程最后执行,那么输出将是1,即使在所有线程完成后计数器值为0。