多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 线程同步问题以及synchronized的引入 我们之前写了个模拟银行排队叫号的demo,这里为了说明问题我把代码稍加改造: ```java public class TicketWindowRunnable implements Runnable { private int index = 1; private static final int MAX = 500; @Override public void run() { while (true) { if (index >= MAX) break; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 的号码是:" + (index++)); } } } ``` 运行效果如下: ![](https://img.kancloud.cn/bd/45/bd457448bfa1ddcf115609c26becef05_960x205.gif) 可以看到我们的运行结果竟然出现了501,其实这个是因为线程同步问题导致的,这在我们并发中经常提到,类似的比如商品超卖等都并发中同时读了数据,然后做了操作。我们来引入synchronized试一下: ```java public class TicketWindowRunnable implements Runnable { private int index = 1; private static final int MAX = 500; private final Object MOINTOR = new Object(); @Override public void run() { while (true) { synchronized (MOINTOR){ if (index >= MAX) break; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 的号码是:" + (index++)); } } } } ``` 运行效果如下: ![](https://img.kancloud.cn/c0/52/c05217efa5045614d8eabdbac43ddb02_960x246.gif) synchronized 它可以把任意一个非 NULL 的对象当作锁。他属于独占式的悲观锁,同时属于可重 入锁。 **Synchronized** **作用范围** 1. 作用于方法时,锁住的是对象的实例(this); 2. 当作用于静态方法时,锁住的是Class实例,又因为Class的相关数据存储在永久带PermGen(jdk1.8 则是 metaspace),永久带是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程; 3. synchronized 作用于一个对象实例时,锁住的是所有以该对象为锁的代码块。它有多个队列。 更多细节我们后续再学习。