一、模拟线程不安全场景。
public class MyRunnable implements Runnable { private int a = 100; //共享的数据 @Override public void run() { while (true) { if (a > 0) { //多个MyRunnable线程同时访问共享数据,结果不是想要的。导致线程不安全 System.out.println(a); a--; } else { break; } } } }
public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); new Thread(myRunnable).start(); new Thread(myRunnable).start(); new Thread(myRunnable).start(); }
二、使用对象监视器解决问题,使其安全。将线程类修改如下。
public class MyRunnable implements Runnable { private int a = 100; //共享的数据 Object obj = new Object(); @Override public void run() { while (true) { //使用了一个锁对象。这种锁又叫:同步锁,对象锁,对象监视器。 synchronized (obj) { if (a > 0) { System.out.println(a); a--; } else { break; } } } } }
对象锁
优点:保证了线程安全,同一时间只能有一个线程执行共享数据。
缺点:程序频繁的判断锁、获取锁和释放锁,程序的效率会降低。