实例变量非线程安全:
如果多个线程共同访问1个对象中的实例变量,则可能出现“非线程安全”问题。
public class UnSafeHasSelfPrivateNum { private int num = 0; public void addI(String username) { try { if (username.equals("a")){ num = 100; System.out.println("a set over!"); Thread.sleep(2000); } else { num = 200; System.out.println("b set over!"); } System.out.println(username + " num = " + num); } catch (InterruptedException e) { e.printStackTrace(); } } } public class UnSafeHasSelfPrivateNumThreadA extends Thread{ private UnSafeHasSelfPrivateNum numRef; public UnSafeHasSelfPrivateNumThreadA(UnSafeHasSelfPrivateNum numRef) { this.numRef = numRef; } @Override public void run() { super.run(); numRef.addI("a"); } } public class UnSafeHasSelfPrivateNumThreadB extends Thread { private UnSafeHasSelfPrivateNum numRef; public UnSafeHasSelfPrivateNumThreadB(UnSafeHasSelfPrivateNum numRef) { this.numRef = numRef; } @Override public void run() { super.run(); numRef.addI("b"); } } public class ThreadRunMain { public static void main(String[] args) { testUnSafeHasSelfPrivateNumThread(); } public static void testUnSafeHasSelfPrivateNumThread(){ UnSafeHasSelfPrivateNum numRef = new UnSafeHasSelfPrivateNum(); UnSafeHasSelfPrivateNumThreadA athread = new UnSafeHasSelfPrivateNumThreadA(numRef); athread.start(); UnSafeHasSelfPrivateNumThreadB bthread = new UnSafeHasSelfPrivateNumThreadB(numRef); bthread.start(); } }
运行结果:
a的值本应该是100,却变成了200. 用synchronized关键字解决问题:
public class UnSafeHasSelfPrivateNum { private int num = 0; synchronized public void addI(String username) { try { if (username.equals("a")){ num = 100; System.out.println("a set over!"); Thread.sleep(2000); } else { num = 200; System.out.println("b set over!"); } System.out.println(username + " num = " + num); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果:
在两个线程访问同一个对象中的同步方法时是线程安全的,先执行a,在执行b。