synchronized锁效率比较低,不方便扩展,不能自定义。于是从jdk1.5之后,就引入了lock锁。
lock可以手动上锁,手动释放锁,灵活性很高。
Lock lock = new ReentrantLock();
lock.lock();
try{
// 可能会出现线程安全的操作
}finally{
// 一定要在finally中释放锁
lock.unlock();
}
lock锁例子
package com.baobaotao;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Printer{
// 打印机
public String fileName;
public String fileType;
boolean flag = true;
Lock lock = new ReentrantLock();
}
class Out extends Thread{
Printer print;
Condition newCon;
public Out(Printer print, Condition newCon){
this.print = print;
this.newCon = newCon;
}
@Override
public void run() {
int count = 0;
while(true){
try{
print.lock.lock();
if(!print.flag){
newCon.await();
}
if(count == 0){
print.fileName = "三国演义";
print.fileType = "pdf";
}else{
print.fileName = "红楼梦";
print.fileType = "txt";
}
count = (count + 1)%2;
print.flag = false;
// 唤醒其他线程
newCon.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
System.out.println("Out--finally--unlock--");
print.lock.unlock();
}
}
}
}
class Input extends Thread{
Printer print;
Condition newCon;
public Input(Printer print, Condition newCon){
this.print = print;
this.newCon = newCon;
}
@Override
public void run() {
while(true){
try{
print.lock.lock();
if(print.flag){
newCon.await();
}
System.out.println(print.fileName+", "+print.fileType);
print.flag = true;
newCon.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
System.out.println("Input--finally--unlock--");
print.lock.unlock();
}
}
}
}
public class OutInputThread extends Thread{
public static void main(String[] args){
Printer print = new Printer();
Condition newCon = print.lock.newCondition();
Out out = new Out(print, newCon);
Input input = new Input(print, newCon);
out.start();
input.start();
}
}