ReentrantLock类也可以实现同步锁的功能,范例:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyObject {
private Lock lock = new ReentrantLock();
public void printNum() {
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.println("ThreadName=" + Thread.currentThread().getName());
}
lock.unlock();
}
}
public class MythreadA extends Thread{
private MyObject obj;
public MythreadA(MyObject obj) {
super();
this.obj = obj;
}
@Override
public void run(){
obj.printNum();
}
}
public class MythreadA extends Thread{
private MyObject obj;
public MythreadA(MyObject obj) {
super();
this.obj = obj;
}
@Override
public void run(){
obj.printNum();
}
}
输出结果:
ThreadName=Thread-0
ThreadName=Thread-0
ThreadName=Thread-0
ThreadName=Thread-0
ThreadName=Thread-0
ThreadName=Thread-1
ThreadName=Thread-1
ThreadName=Thread-1
ThreadName=Thread-1
ThreadName=Thread-1
ThreadName=Thread-2
ThreadName=Thread-2
ThreadName=Thread-2
ThreadName=Thread-2
ThreadName=Thread-2
ThreadName=Thread-3
ThreadName=Thread-3
ThreadName=Thread-3
ThreadName=Thread-3
ThreadName=Thread-3
ThreadName=Thread-4
ThreadName=Thread-4
ThreadName=Thread-4
ThreadName=Thread-4
ThreadName=Thread-4
使用Condition实现等待/通知
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyObject {
private ReentrantLock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await() {
try {
lock.lock();
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("await time: " + System.currentTimeMillis());
try {
condition.await();
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
lock.unlock();
}
}
public void signal() {
try {
lock.lock();
System.out.println("signal time:" + System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
}
public class MythreadA extends Thread{
private MyObject obj;
public MythreadA(MyObject obj) {
super();
this.obj = obj;
}
@Override
public void run(){
obj.await();
}
}
public class Main {
public static void main(String[] args) {
MyObject myObject = new MyObject();
MythreadA mythreadA = new MythreadA(myObject);
mythreadA.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myObject.signal();
}
}
condition.signalAll函数可以唤醒所有线程。
lock其他函数:
Lock lock = new ReentrantLock(false);
可传入参数,表示是否是公平锁,公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的。默认是不公平锁
lock.getHoldCount();查询当前线程保持此锁的个数,即调用lcok方法的次数。
lock.getQueueLength();
返回证等待获取此锁定的线程估计数。比如有5个线程,1个线程首先执行await方法,那调用getQueueLength方法后返回值是4,说明有4个线程同时在等待lock的释放
lock.getWaitQueueLength(Condition condition);
放回等待此锁先关给定条件Condition的线程估计数。比如有5个线程,每个线程都执行了同一个condition的await()方法,则调用getWaitQueueLength方法返回的int值是
lock.hasQueuedThread(Thread.currentThread());
查看指定线程是否在等待获取这个锁定。
boolean lock.hasWaiters(condition);
查询是否线程有正在等待与此锁有关的condition条件。
boolean lock.isFair();
判断这个是不是不公平锁。
boolean lock.isHeldByCurrentThread();
查询当前线程是否保持此锁。
boolean lock.isLocked()
查询此锁是否由任一线程保持。
boolean lock.lockInterruptibly();
如果当前线程未被中断,则获取该锁,如果已经被中断则出现异常。
boolean lock.tryLock(long timeout,TimeUnit unit);
仅在调用时锁未被另外一个线程保持的情况下,才获取该锁。
condition.awaitUninterruptibly();
线程在调用condition.await()后处于await状态,此时调用thread.interrupt()会报错.
但是使用condition.awaitUninterruptibly()后,调用thread.interrupt()则不会报错
boolean condition.awaitUntil(Date deadline).
condition.awaitUntil(Date deadline)在等待时间之内可以被其它线程唤醒,等待时间一过该线程会自动唤醒,和别的线程争抢锁资源
condition.await(long)和condition.awaitUtil(Date deadline)和thread.wait(long)用法一样