import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockThread extends Thread{
private Lock lock;
private static int num=0;
public LockThread(Lock lock) {
this.lock=lock;
}
@Override
public void run() {
for(int i=0;i<100000;i++){
try {
lock.lock();
lock.lock();
num++;
}finally {
lock.unlock();
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
LockThread lockThread1 = new LockThread(lock);
LockThread lockThread2 = new LockThread(lock);
lockThread1.start();
lockThread2.start();
lockThread1.join();
lockThread2.join();
System.out.println(LockThread.num);
}
}
lock.lock()一般写在try代码块中,lock.unlock()写在finally代码块中,Lock是一个抽象类,ReentrantLock()也存在可重入性,ReentrantLock(true)可以保证线程的公平性(synchronized是非公平锁,唤醒线程时是随机唤醒的)
lock.lockInterruptibly()当前线程没有中断就会获得锁,如果线程被中断机会报错
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockThread extends Thread{
private Lock lock;
public LockThread(Lock lock) {
this.lock=lock;
}
@Override
public void run() {
try {
lock.lockInterruptibly();
System.out.println(Thread.currentThread().getName()+"线程获得锁");
sleep(1000);
lock.unlock();
System.out.println(Thread.currentThread().getName()+"线程释放");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
LockThread lockThread1 = new LockThread(lock);
LockThread lockThread2 = new LockThread(lock);
lockThread1.start();
sleep(50);//保证lockThread1获得锁
lockThread2.start();
sleep(50);
lockThread2.interrupt();//中断lockThread2线程
}
}
当lockThread1获得锁后,lockThread2线程运行后中断lockThread2线程 lock.lockInterruptibly()机会报错。
ReentrantLock中的isHeldByCurrentThread方法:当前线程是否持有锁
lock.tryLock(long time, TimeUnit unit)在给定时长内‘锁’没有其他线程持有,当前线程也没有被中断则获得锁。获得锁返回true,没有获得锁返回false,tryLock()无参方法不会等待,如果锁被其他线程使用就会返回false。
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockThread extends Thread{
private ReentrantLock lock;
public LockThread(ReentrantLock lock) {
this.lock=lock;
}
@Override
public void run() {
try {
if( lock.tryLock(3, TimeUnit.SECONDS)){ //等待3秒
System.out.println(Thread.currentThread().getName()+"线程获得锁");
// sleep(1000); //一个线程运行的时间小于3秒最后运行的线程会获得锁
sleep(10000); //一个线程运行的时间大于3秒最后运行的线程会获得锁
}else{
System.out.println(Thread.currentThread().getName()+"线程没有获得锁");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if(lock.isHeldByCurrentThread()){ //当前线程是否持有锁
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
LockThread lockThread1 = new LockThread(lock);
LockThread lockThread2 = new LockThread(lock);
lockThread1.start();
lockThread2.start();
}
}
Lock lock=new ReentrantLock();Condition condition=lock.newCondition(); 获得Condition实例。 condition.await();//线程等待 condition.signal();//唤醒线程类似Object的wait/notify方法
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionTest extends Thread{
static Lock lock=new ReentrantLock();
static Condition condition=lock.newCondition();
@Override
public void run() {
try {
lock.lock();
System.out.println("开始等待");
condition.await();//线程等待
System.out.println("等待结束");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
ConditionTest conditionTest = new ConditionTest();
conditionTest.start();
try {
Thread.sleep(3000);
lock.lock();
condition.signal(); //唤醒线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
lock.getHoldCount()当前线程调用lock()的次数
lock.getQueueLength()等待队列中线程的数量
lock.getWaitQueueLength(condition)与condition相关的等待队列中线程的预估数量
lock.hasQueuedThread(thread)指定线程是否在等待获得锁
lock.hasQueuedThreads()是否有线程在等待锁
lock.hasWaiters(condition)是否有线程在等待指定的condition
lock.isFair()判断是否是公平锁
lock.isLocked()当前锁是否被线程持有
读锁之间存在共享锁(所有读线程异步执行),读锁与写锁存在排他性。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class LockTest {
static class ReadWriteLockTest {
ReadWriteLock lock=new ReentrantReadWriteLock();
public void read(){
try {
lock.readLock().lock(); //获得读锁
System.out.println(Thread.currentThread().getName()+"获取读锁:"+System.currentTimeMillis());
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+"读锁完成:"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.readLock().unlock();
}
}
public void write(){
try {
lock.writeLock().lock(); //获得读锁
System.out.println(Thread.currentThread().getName()+"获取写锁:"+System.currentTimeMillis());
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+"写锁完成:"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
}
}
public static void main(String[] args) {
ReadWriteLockTest readWriteLockTest= new ReadWriteLockTest();
for (int i=0;i<5;i++){
new Thread(new Runnable() {
@Override
public void run() {
readWriteLockTest.read();
}
}).start();
}
for (int i=0;i<5;i++){
new Thread(new Runnable() {
@Override
public void run() {
readWriteLockTest.write();
}
}).start();
}
}
}