Java 学习笔记之 实例变量非线程安全

mac2022-06-30  53

实例变量非线程安全:

 

如果多个线程共同访问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。

 

转载于:https://www.cnblogs.com/AK47Sonic/p/7705584.html

最新回复(0)