Java多线程问题:如何用一个线程累加变量,另一个线程定期打印
Java多线程计数器实现:累加与定期打印
核心问题是线程间的变量可见性和共享变量作用域:如果累加的变量是局部变量,打印线程根本访问不到;就算是成员变量,没有保证可见性的话,打印线程读取的可能是缓存里的初始旧值(也就是你看到的0)。下面是几种可行的实现方案:
方案1:用volatile修饰共享变量
volatile可以强制线程直接从主内存读写变量,保证一个线程修改后,其他线程能立刻看到最新值,适合简单的累加场景:
public class CounterDemo { // 用volatile保证变量可见性 private volatile int count = 0; public static void main(String[] args) { CounterDemo demo = new CounterDemo(); // 累加线程 Thread incrementThread = new Thread(() -> { while (true) { demo.count++; try { Thread.sleep(100); // 模拟累加耗时 } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); // 打印线程 Thread printThread = new Thread(() -> { while (true) { System.out.println("当前计数:" + demo.count); try { Thread.sleep(500); // 每500ms打印一次 } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); incrementThread.start(); printThread.start(); } }
方案2:用AtomicInteger原子类
如果需要保证累加操作的原子性(高并发下不会出现计数丢失),可以用java.util.concurrent.atomic包下的AtomicInteger,它本身就兼顾了可见性和原子操作:
import java.util.concurrent.atomic.AtomicInteger; public class AtomicCounterDemo { private AtomicInteger count = new AtomicInteger(0); public static void main(String[] args) { AtomicCounterDemo demo = new AtomicCounterDemo(); Thread incrementThread = new Thread(() -> { while (true) { demo.count.incrementAndGet(); // 原子性累加 try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); Thread printThread = new Thread(() -> { while (true) { System.out.println("当前计数:" + demo.count.get()); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); incrementThread.start(); printThread.start(); } }
方案3:用synchronized同步锁
如果需要更复杂的同步逻辑,synchronized可以同时保证可见性和原子性,通过锁机制控制变量的读写:
public class SyncCounterDemo { private int count = 0; // 同步累加方法 public synchronized void increment() { count++; } // 同步获取计数方法 public synchronized int getCount() { return count; } public static void main(String[] args) { SyncCounterDemo demo = new SyncCounterDemo(); Thread incrementThread = new Thread(() -> { while (true) { demo.increment(); try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); Thread printThread = new Thread(() -> { while (true) { System.out.println("当前计数:" + demo.getCount()); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); incrementThread.start(); printThread.start(); } }
内容的提问来源于stack exchange,提问作者floralys352
相关产品推荐
相关产品推荐

