01 synchronized
每个对象都有一个锁
对象锁分为三种:共享资源、this、当前类的字节码文件对象
当某个线程获取到锁对象,其他线程要获取但获取不到时,会进入阻塞状态
synchronized锁的是对象,不是代码
是非公平锁
缺点
(1) 效率低,频繁的判断锁,获取锁,释放锁
(2) 无法中断正在阻塞获得锁的线程,Lock锁可以中断(设置超时时间)
(3) 无法通过投票得到锁,如果不想等下去,也就没法得到锁
(4) 同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行,多数情况下,这没问题(而且与异常处理交互得很好),但是,确实存在一些非块结构的锁定更合适的情况
02 作用
保证原子性,可见性,可重入性
使用方法一,同步代码块
线程同步 同步代码块 锁机制 同步锁 对象锁 也叫对象监视器
锁对象可以是任意对象 但不能用匿名对象 匿名对象不是同一个对象
下面代码里面的锁对象必须是一个对象
public class Test {
public static void main(String[] args) {
final Printer printer = new Printer();
new Thread() {
@Override
public void run() {
while (true) {
printer.printOne();
}
}
}.start();
new Thread() {
@Override
public void run() {
while (true) {
printer.printTwo();
}
}
}.start();
}
}
class Printer {
Demo demo = new Demo();
public void printOne () {
synchronized (demo) {
System.out.println("1");
System.out.println("2");
System.out.println("3");
}
}
public void printTwo () {
synchronized (demo) {
System.out.println("A");
System.out.println("B");
System.out.println("C");
}
}
}
class Demo {}
使用方式二 同步方法
非静态方法
非静态同步方法和同步代码块(使用this锁),可以证明非同步静态同步方法的锁是this
把放方法中的内容写在一个用this上锁的同步代码块中,把这个同步代码块放在方法中
静态同步方法
锁对象是该类的字节码对象
和使用同步代码块锁对象使用当前类的字节码文件效果一样
同步方法和同步块,哪个选择好
同步方法的锁对象是this,会锁住整个对象,这个对象里面其他的带有synchronized的方法都会同步
同步代码快不会锁着整合对象,只锁住当前代码块,符合开放调用的原则 范围小,性能好
要看具体业务使用哪一个