synchronized关键字
1.修饰普通方法:
锁住对象的实例
public synchronized void out() throws InterruptedException {
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000L);
}
如果new了两个实例,则该两个实例互不干扰,不需要等待对方的锁。
2.修饰静态方法:
锁住整个类
public static synchronized void staticOut() throws InterruptedException {
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000L);
}
如果new了两个实例同时调用该方法,则执行一个,另一个等待锁。
3.修饰代码块:
锁住一个对象 synchronized (lock)
private Object lock = new Object();
public void myOut() {
synchronized (lock) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
volatile关键字
1.只能修饰变量,保证该变量的可见性,volatile关键字仅仅保证可见性,并不保证原子性.
A、B两个线程同时读取volatile关键字修饰的对象,A读取之后,修改了变量的值。修改后的值,对B线程来说,是可见
2.禁止指令重排序
使用场景
1:作为线程开关
2:单例,修饰对象实例,禁止指令重排序