一 什么是 synchronized
synchronized 关键字提供了一种锁机制,能够确保共享变量互斥访问,从而防止数据不一致问题的出现。
synchronized 关键字包括 monitor enter 和 monitor exit 两个 JVM 指令,它能够保证在任何时候任何线程执行到 monitor enter 成功之前必须从主内存中获取数据,而不是从缓存中,在 monitor exit 运行成功之后,共享变量被更新后的值必须刷入主内存。
synchronized 的指令严格遵守 java happens-before 规则,一个 monitor exit 指令之前必定有一个 mnitor enter。
二 synchronized 关键字的用法
synchronized 可对代码块或方法进行修饰,而不能对 class 以及变量进行修饰。
1 同步方法
public synchronized void sync(){
......
}
public synchronized static void staticSync(){
......
}
2 同步代码块
private final Object MUTEX = new Object();
public void sync(){
synchronized(MUTEX){
......
}
}
三 使用 synchronized 关键字解决营业大厅叫号程序问题
1 代码
package concurrent;
public class TicketWindowRunnable1 implements Runnable {
private int index = 1;
private final static int MAX = 50;
private final static Object MUTEX = new Object();
@Override
public void run() {
synchronized (MUTEX) {
while (index <= MAX) {
System.out.println(Thread.currentThread() + "的号码是:" + (index++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final TicketWindowRunnable1 task = new TicketWindowRunnable1();
Thread windowThread1 = new Thread(task, "1号窗口");
Thread windowThread2 = new Thread(task, "2号窗口");
Thread windowThread3 = new Thread(task, "3号窗口");
Thread windowThread4 = new Thread(task, "4号窗口");
windowThread1.start();
windowThread2.start();
windowThread3.start();
windowThread4.start();
}
}
2 测试
上面程序无论运行多少次,都不会出现数据不一致问题。