线程同步问题求助:我使用如下代码实现线程同步时遇到问题
排查你的线程同步问题
先看你给出的代码片段,首先有个明显的小问题:第二个线程t2的Runnable实现代码不完整(@O...这里截断了),如果t2的run方法里没有像t1那样循环调用increment(),那线程同步自然没起到作用,这是首先要确认的点。
假设t2的run方法和t1一致,都是循环10000次调用increment(),那我们来分析代码的线程安全性:
count是静态变量,属于类级别的共享资源;increment()是静态同步方法,它的锁对象是Demo4.class这个类本身。当t1和t2调用这个方法时,都会竞争同一把锁,所以count++这个操作会被原子化执行,理论上不会出现线程安全问题。
那为什么你还是遇到了线程同步问题?大概率是这几个隐藏问题:
主线程没有等待子线程完成就读取count
如果你的main方法在创建t1、t2并启动后,直接去打印count的值,那主线程可能在t1和t2还没执行完的时候就输出了,导致结果不符合预期。比如:// 错误示例:主线程直接打印,没等子线程结束 t1.start(); t2.start(); System.out.println(count); // 这里得到的可能不是20001修正方法是调用
join()等待两个线程完成:t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count); // 此时应该得到正确的20001存在其他未同步的count修改操作
如果你的实际代码中,除了increment()方法,还有其他地方直接修改count(比如在某个线程里直接写count++而不调用同步方法),那这些操作会绕过锁机制,导致线程安全问题。比如:// 错误示例:直接修改count,没有同步 Thread t3 = new Thread(() -> { for (int i = 1; i <= 10000; i++) { count++; // 这里没有同步,会和其他线程的操作冲突 } });这种情况要确保所有修改
count的操作都通过同步方法或者显式锁来控制。代码截断导致的逻辑缺失
你给出的t2代码不完整,如果t2的run方法里执行的是其他逻辑,没有调用increment(),那自然不会对count产生预期的修改效果。
最后,给你一份完整的可验证代码参考:
package pkg.com.thread1; public class Demo4 { private static int count = 1; public synchronized static void increment() { count++; } public static void main(String[] args) { Thread t1 = new Thread(() -> { for (int i = 1; i <= 10000; i++) { increment(); } }); Thread t2 = new Thread(() -> { for (int i = 1; i <= 10000; i++) { increment(); } }); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("最终count值:" + count); // 预期输出20001 } }
内容的提问来源于stack exchange,提问作者Sanjeev Roy
相关产品推荐
相关产品推荐

