synchronized锁
synchronized是Java的关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、D等)正在用这个方法,有的话要等正在使用synchronized方法的线程B(或者C、D)运行完这个方法后再运行此线程A,没有的话,直接运行。它包括两种用法:synchronized方法和synchronized块。
用生活中的例子讲就是,你去银行取钱,得排队,轮到你了才能取钱,这就是加了synchronized锁的情况,一个取款机一个时间只能让一人取钱。而没有synchronized锁,那就会出现乱插队的现象
synchronized锁使用
- 对一个方法进行加锁
// 未加锁的方法
public void test() {}
// 加锁后的方法
pubilc synchronized void test() {}
- synchronized 也可以用在一个代码块上
public void test() {
synchronized(obj) {
System.out.println("===");
}
}
- synchronized 通常与wait()、notify()、nitifyAll()一起使用。
wait():释放占有的对象锁,线程进入等待池,释放cpu,而其他正在等待的线程即可抢占此锁,获得锁的线程即可运行程序。
【wait()和sleep()最大的不同在于wait()会释放对象锁,而sleep()不会】
notify(): 该方法会唤醒因为调用对象的wait()而等待的线程。
notifyAll()则是唤醒所有等待的线程。
关于synchronized的详细剖析,推荐看这篇让你彻底理解Synchronized
lock锁
lock的出现是为了解决synchronized不能手动上锁开锁的问题
lock用法
Lock lock = new ReentrantLock();
lock.lock();
try{
//可能会出现线程安全的操作
}finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
lock.ublock();
}
synchronized和lock的区别
1.synchronized 是内置的Java关键字,lock是一个Java类
2.synchronized 无法判断获取锁的状态,lock可以判断是否获取到了锁
3.synchronized 会自动释放锁,lock 必须手动释放锁,如不释放,会出现死锁
4. synchronized 当线程1获得锁后发生阻塞时,线程2就会一直等待下去,lock锁则不一定会等待下去
5. synchronized 适合少量的代码同步问题,lock 适合锁大量的同步代码。