Lock与Synchronized区别
Lock不是JAVA内置,Synchronized是Java关键字,是内置的。
Synchronized不用手动释放锁,Lock需要手动释放锁,否则有可能造成死锁
Lock可以让等待锁的线程众多,Synchronized不行
Lock可以知道有没有成功获取锁,Synchronized不行
Lock可以提高多个线程进行读操作效率
线程通信
Synchronized常与wait(),notifyAll()连用,Lock常与awit(),signalAll()连用
private Lock lock = new ReentrantLock();
Condition condition=lock.newCondition();
//上锁
lock.lock();
//判断
while(){
condition.await();
}
//干活
//通知
condition.signalAll();
//解锁 最好写在finally里保证肯定执行
lock.unlock();
//线程通信 方法一:
//可能出现虚假唤醒,
while(){
this.wait();//唤醒后从等待的地方开始,所以this.wait()最好加在while()之间
}
this.notifyAll();
//方法二:用Lock
while(){
condition.await();//唤醒后从等待的地方开始,所以this.wait()最好加在while()之间
}
condition.signalAll();
案例
/*打印A一次 B两次 C三次
循环十次*/
public class Print {
private int flag = 1;
private Lock l = new ReentrantLock();
Condition c1 = l.newCondition();
Condition c2 = l.newCondition();
Condition c3 = l.newCondition();
public void A(int loop) throws InterruptedException {
// Lock l = new ReentrantLock();
l.lock();
while (flag != 1) {
c1.await();
}
System.out.println("A"+loop);
flag = 2;
c2.signalAll();
l.unlock();
}
public void B(int loop) throws InterruptedException {
// Lock l = new ReentrantLock();
l.lock();
while (flag != 2) {
c2.await();
}
for (int i = 0; i < 2; i++) {
System.out.println("B"+loop);
}
flag = 3;
c3.signalAll();
l.unlock();
}
public void C(int loop) throws InterruptedException {
// Lock l = new ReentrantLock();
l.lock();
while (flag != 3) {
c3.await();
}
for (int i = 0; i < 3; i++) {
System.out.println("C"+loop);
}
flag = 1;
c1.signalAll();
l.unlock();
}
public static void main(String[] args) {
Print p = new Print();
new Thread(() -> {
try {
for (int i = 1; i <10 ; i++) {
p.B(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
for (int i = 1; i <10 ; i++) {
p.C(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
for (int i = 1; i <10 ; i++) {
p.A(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}