我正在尝试在多线程环境中对int变量进行经典的递增/递减。这是我的示例代码。
public class SyncIncDec { public static void main(String[] args) { SyncCounter count = new SyncCounter(); Thread incThread = new Thread(() -> { count.increment(); }); Thread decThread = new Thread(() -> { count.decrement(); }); Thread displayThread = new Thread(() -> { System.out.println("Count value : " + count.getX()); }); incThread.start(); decThread.start(); displayThread.start(); try { incThread.join(); } catch (InterruptedException e) { // e.printStackTrace(); } try { decThread.join(); } catch (InterruptedException e) { // e.printStackTrace(); } try { displayThread.join(); } catch (InterruptedException e) { // e.printStackTrace(); } } } class SyncCounter { private int x=0; public SyncCounter() { super(); } public SyncCounter(int y) { super(); x = y ; } synchronized int getX() { return x; } void setX(int y) { x = y ; } void increment() { ++x; } void decrement() { --x; } }
尽管我对所有三个线程都使用了join()方法,但结果仍然不一致。在这里加入不是意味着主线程要等到每个线程都完成执行吗?我什至尝试将同步添加到三个方法签名中的每个;但是我得到不一致的结果。
除了使用该变量的Atomic版本外,我还能如何确保始终获得0?
您的SyncCounter根本不是线程安全的。可变方法的增量和减量应同步。现在,实现此类的正确方法是原子式的。例如:
class SyncCounter { private final AtomicInteger x; public SyncCounter() { this(0); } public SyncCounter(int x) { this.x = new AtomicInteger(x); } int getX() { return x.get(); } void setX(int x) { this.x.set(x); } int increment() { return x.incrementAndGet(); } int decrement() { return x.decrementAndGet(); } }
和测试代码:
final Thread incThread = new Thread(() -> { count.increment(); }); final Thread decThread = new Thread(() -> { count.decrement(); }); Thread displayThread = new Thread(() -> { incThread.join(); decThread.join(); System.out.println("Count value : " + count.getX()); });