ReentrantLock
ReentrantLock可以实现可重入锁。可以替代synchronized。ReentrantLock更加灵活。下面是ReentrantLock使用案例:
public class ReenterLockTest implements Runnable{
private static final ReentrantLock lock = new ReentrantLock();
private static long count = 0;
private static CountDownLatch countDown = new CountDownLatch(10);
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for(int i = 0 ; i < 10 ; ++i) {
threadPool.submit(new ReenterLockTest());
}
try {
countDown.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
threadPool.shutdown();
System.out.println(count);
}
@Override
public void run() {
try {
lock.lock();
for(int i = 0 ; i < 10000 ; i++) {
count ++;
}
countDown.countDown();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
ReentrantLock可以实现所申请时间限时。通过限时设置避免线程等待。tryLock()立即返回获取锁结果。tryLock(time,timeutil)在给定时间内尝试返回获取锁结果。
public class ReenterLockTest implements Runnable{
private static final ReentrantLock lock = new ReentrantLock();
private static long count = 0;
private static CountDownLatch countDown = new CountDownLatch(10);
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for(int i = 0 ; i < 10 ; ++i) {
threadPool.submit(new ReenterLockTest());
}
try {
countDown.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
threadPool.shutdown();
System.out.println(count);
}
@Override
public void run() {
try {
while(true) {
if(lock.tryLock(1, TimeUnit.SECONDS)) {
for(int i = 0 ; i < 10000 ; i++) {
count ++;
}
countDown.countDown();
break;
}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
ReentrantLock lock = new ReentrantLock(true);可以实现公平锁。如果希望先申请锁的线程先获得锁,可以通过公平锁来实现。案例省略。 ReentrantLock 通过condition条件实现线程之间的通知。condition条件控制可以比synchronized更细,类似Object.wait,notify,notifyAll。Condition.await,signal,signalAll通过condition实现多消费者多生产者。
public class ReenterLockTest{
private static final ReentrantLock lock = new ReentrantLock();
private static final Condition consumCon = lock.newCondition();
private static final Condition prudutCon = lock.newCondition();
private static List<Integer> productLis = new ArrayList<Integer>(3);
public static void main(String[] args) {
List<Thread> threads = new ArrayList<>();
for(int i = 0 ; i < 6 ; i++) {
if(i < 3) {
Thread t = new Thread(new AddWork());
t.setName("生产者线程"+ i);
threads.add(t);
}else {
Thread t1 = new Thread(new RedWork());
t1.setName("消费者线程"+ i);
threads.add(t1);
}
}
for(Thread t : threads) {
t.start();
}
}
static class AddWork implements Runnable{
@Override
public void run() {
for(;;) {
try {
for(;;) {
if(lock.tryLock(3, TimeUnit.SECONDS)) {
while(productLis.size() >= 3) {
prudutCon.await();
}
System.out.println("线程["+Thread.currentThread().getName()+"]添加");
productLis.add(1);
consumCon.signalAll();
break;
}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
}
static class RedWork implements Runnable{
@Override
public void run() {
for(;;) {
try {
for(;;) {
if(lock.tryLock(3, TimeUnit.SECONDS)) {
while(productLis.size() == 0) {
consumCon.await();
}
System.out.println("线程["+Thread.currentThread().getName()+"]消费");
productLis.remove(0);
prudutCon.signalAll();
break;
}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
}
}