Lock
1、getHoldCount()
查询当前线程保持此锁锁定的个数,也就是调用lock方法的次数
2、int getQueueLength
返回正等待此锁定的线程估计数,例如有5个线程,1个线程首先执行await,那么调用getQueueLength返回4
3、int getWaitQueueLength(Condition condition)
返回等待与次锁定相关的给定条件Condition的线程估计数,例如有5个线程,每个线程都执行了同一个condition对象的await方法,则调用此方法返回5.
4、boolean hasQueuedThreads
查询是否有线程正在等待获取此锁定,lock.hasQueuedThread(thread)
5、boolean hasWaiters(Condition condition)
查询是否有线程正在等待与此锁定有关的condition条件
lock.hasWaiters(condition)线程数是lock.getWaitQueueLength(condition)
6、isFair
判断是否是公平锁
7、boolean isHeldByCurrentThread
查询当前线程是否保持此锁定
8、lockInterruptibly()
如果当前线程未被中断,则获取锁定,如果已经被中断则抛出异常
9、boolean tryLock()
仅在调用时锁定未被另一个线程保持的情况下,才获取 该锁定。
10、boolean tryLock(long timeout,TimeUnit unit)
如果锁定给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定,例如:
package com.fyw.thread.lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ServiceMethod {
public ReentrantLock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void awaitMethod(){
try{
if(lock.tryLock(3,TimeUnit.SECONDS)){
System.out.println(Thread.currentThread().getName()+"获得锁的时间:"+System.currentTimeMillis());
Thread.sleep(4000);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
public void notifyMethod(){
try{
lock.lock();
System.out.println("有"+lock.getWaitQueueLength(condition)+"个线程等待condition");
condition.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
final ServiceMethod service = new ServiceMethod();
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"调用waitMethod时间:"+System.currentTimeMillis());
service.awaitMethod();
}
};
Thread threadA = new Thread(runnable);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnable);
threadB.setName("B");
threadB.start();
}
输出:
A调用waitMethod时间:1544957162945
B调用waitMethod时间:1544957162945
A获得锁的时间:1544957162946
如果将sleep(4000)改成1000,输出如下:
A调用waitMethod时间:1544957292643
B调用waitMethod时间:1544957292643
B获得锁的时间:1544957292643
A获得锁的时间:1544957293643
【使用Condition实现线程顺序交叉执行】
package com.fyw.thread.lock.condition;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Run {
volatile private static int nextRun = 1;
private static Lock lock = new ReentrantLock();
private static Condition condition1 = lock.newCondition();
private static Condition condition2 = lock.newCondition();
private static Condition condition3 = lock.newCondition();
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable(){
@Override
public void run() {
try {
lock.lock();
while(nextRun != 1){
condition1.await();
}
for(int i=0;i<3;i++){
System.out.println("Thread1 "+(i+1));
}
nextRun = 2;
condition2.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
});
Thread thread2 = new Thread(new Runnable(){
@Override
public void run() {
try {
lock.lock();
while(nextRun != 2){
condition2.await();
}
for(int i=0;i<3;i++){
System.out.println("Thread2 "+(i+1));
}
nextRun = 3;
condition3.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
});
Thread thread3 = new Thread(new Runnable(){
@Override
public void run() {
try {
lock.lock();
while(nextRun != 3){
condition3.await();
}
for(int i=0;i<3;i++){
System.out.println("Thread3 "+(i+1));
}
nextRun = 1;
condition1.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
});
Thread[] array1 = new Thread[5];
Thread[] array2 = new Thread[5];
Thread[] array3 = new Thread[5];
for(int i=0;i<5;i++){
array1[i] = new Thread(thread1);
array2[i] = new Thread(thread2);
array3[i] = new Thread(thread3);
array1[i].start();
array2[i].start();
array3[i].start();
}
}
}
【执行结果如下】
Thread1 1
Thread1 2
Thread1 3
Thread2 1
Thread2 2
Thread2 3
Thread3 1
Thread3 2
Thread3 3
Thread1 1
Thread1 2
Thread1 3
Thread2 1
Thread2 2
Thread2 3
Thread3 1
Thread3 2
Thread3 3
Thread1 1
Thread1 2
Thread1 3
Thread2 1
Thread2 2
Thread2 3
Thread3 1
Thread3 2
Thread3 3
Thread1 1
Thread1 2
Thread1 3
Thread2 1
Thread2 2
Thread2 3
Thread3 1
Thread3 2
Thread3 3
Thread1 1
Thread1 2
Thread1 3
Thread2 1
Thread2 2
Thread2 3
Thread3 1
Thread3 2
Thread3 3
【读写锁ReentrantReadWriteLock】
读读共享、读写互斥、写写互斥
【读读共享】
package com.fyw.thread.lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadReadLock {
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void read(){
try {
readWriteLock.readLock().lock();
System.out.println("线程"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"获得read锁");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
readWriteLock.readLock().unlock();
}
}
public static void main(String[] args) {
ReadReadLock rrl = new ReadReadLock();
ThreadA threadA = new ThreadA(rrl);
threadA.setName("A");
threadA.start();
ThreadB threadB = new ThreadB(rrl);
threadB.setName("B");
threadB.start();
}
}
【运行结果】
线程B并没有等到Asleep(10000)之后再执行,而是一起执行
线程A在1544972110700获得read锁
线程B在1544972110701获得read锁
读写、写写用法同上