public class TT implements Runnable { // 属性 b 初始值为100 int b = 100; public synchronized void m1() throws InterruptedException { b = 1000; Thread.sleep(5000); System.out.println("b = "+b); } public synchronized void m2(){ System.out.println(b); b = 998; System.out.println("m2 更改后的——"+b); } @Override public void run() { try { m1(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { TT tt = new TT(); Thread t = new Thread(tt); t.start(); // 开启线程后就 给 b 赋值为1000 ,然后t 线程睡眠5秒 , //主线程睡眠1秒,主线程(main)继续执行 , //调用m2方法打印 b 因为在主线程进来之前,b 已经被m1()方法修改为1000,所有直接执行 打印1000 //t 线程 醒来后继续打印 也是 1000 //主线程睡眠 1 秒 Thread.sleep(1000); tt.m2(); //为什么t 线程醒来后 打印的值 b 为什么 不是 主线程修改后的值? //因为 t线程,开启以后,t线程是一个独立的栈。在栈中修改的b的值是对象的属性 //,存在的位置在堆中,此时的b地址 执向 0x001 存的值是 1000. 开始睡觉 //主线程 修改后b的值为 998 :内存中发生的事情是:b的地址 指向0x002 存储的值是998。 //根本原理是: 线程 和 线程中 是相互独立的栈。共享的是堆中和方法区的内存。 b这个变量是存在栈中的。 } }
// 运行结果 :
// b = 1000
// 1000
// m2 更改后的——998
个人理解: 请谨慎食用!