无显式共享数据却出现线程不安全?多线程编程疑问
线程安全疑问:无显式共享数据却出现线程不安全问题
我是多线程编程新手,之前被告知线程不安全问题总是由多线程间的共享资源导致,这逻辑上说得通,但我的代码里好像没有线程间共享的数据,却出现了线程不安全问题。
代码示例
Outputer类
package test; public class Outputer{ public void output(){ String name = "123456789"; int len = name.length(); for(int i=0;i<len;i++){ System.out.print(name.charAt(i)); } System.out.println(); } }
主类
package test; public class TraditionalThreadSynchronized { public static void main(String[] args) { Outputer outputer = new Outputer(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i <= 50; i++) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output(); } } }).start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i <= 50; i++) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output(); } } }).start(); } }
异常输出情况
我预期每次输出都是完整的123456789,但实际有时会出现输出混乱:
... ... 123456789 123456789 123456789 123456789 123456789 123456789 // 预期输出 112323456789 // 异常输出 456789 // 异常输出 123456789 123456789 123456789 123456789 123456789 ... ...
我的理解
我知道问题出在这段非原子操作的代码块:
for(int i=0;i<len;i++){ System.out.print(name.charAt(i)); } System.out.println();
我已经通过给代码块加synchronized块修复了问题,现在输出正常。但我还有两个疑问:
- 「线程不安全问题总是由多线程间的共享资源导致」这一论断是否始终成立?
- 如果成立,我的示例中线程共享的是什么资源?如果不成立,还有哪些无共享数据的线程不安全场景?
问题解答
1. 该论断是始终成立的
线程不安全的本质是多个线程对共享资源的非同步访问,只要出现线程不安全问题,必然存在被多线程共享且未被正确同步的资源。
2. 你的示例中共享的资源是System.out(标准输出流)
你代码里的System.out.print()和System.out.println()操作的是JVM全局的标准输出流,这个流是所有线程共享的公共资源。虽然name是方法内的局部变量(线程私有),但输出依赖的PrintStream实例(System.out指向的对象)是全局共享的。
当两个线程同时调用print()时,它们会交替写入这个共享的输出流,导致字符被交叉输出,最终出现混乱结果。添加synchronized后,相当于给输出操作加了互斥锁,确保同一时间只有一个线程能操作输出流,从而避免了交叉写入。
3. 不存在完全无共享数据的线程不安全场景,但共享资源可能很隐蔽
有些场景下共享资源并非显式定义的变量,而是隐藏的系统或JVM内部资源:
- 隐式共享的系统资源:比如标准输入输出流、文件句柄、网络套接字等,这些都是进程内所有线程共享的系统级资源。
- JVM内部的共享状态:比如类加载器的状态、JIT编译器的缓存等,这些资源对开发者透明,但多线程操作时若未同步,也可能引发问题。
- 指令重排序导致的协作异常:即使线程操作自己的局部变量,若涉及和其他线程的状态协作(比如通过
volatile或锁传递状态),错误的指令重排序也可能导致逻辑异常,但本质还是因为线程间需要共享状态完成协作,只是状态传递过程出了问题。
内容的提问来源于stack exchange,提问作者Andy Li
相关产品推荐
相关产品推荐

