例1:
package service;
public class Run {
public static void main(String[] args) {
// 线程打印完毕后将锁进行释放,其他线程才能进行继续打印,线程之间的打印顺序是随机的
MyService service = new MyService();
MyThread a1 = new MyThread(service);
MyThread a2 = new MyThread(service);
MyThread a3 = new MyThread(service);
MyThread a4 = new MyThread(service);
MyThread a5 = new MyThread(service);
a1.start();
a2.start();
a3.start();
a4.start();
a5.start();
}
}
ReentrantLock对象的lock方法用来获取锁,unlock方法用来释放锁
例2:
package service01;
public class Run {
//使用ReentrantLock实现同步
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.start();
Thread.sleep(100);
ThreadB b = new ThreadB(service);
b.start();
}
}
4.1.3使用Condition实现等待通知机制
关键字synchronized与wait()/notify()/notifyAll()可以实现等待通知模式,但是被通知的线程是由JVM随机选择,但是ReentrantLock结合Condition可以实现选择性通知
在一个Lock对象中可以创建多个Condition(对象监视器)实例,线程对象可以创建在指定的Condition中
package service02;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void await() {
try {
lock.lock();
System.out.println("A");
condition.await();
System.out.println();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void signal() {
try {
lock.lock();
System.out.println("signal:"+System.currentTimeMillis());
condition.signal();
}finally {
lock.unlock();
}
}
}
4.1.4正确使用Condition实现等待通知
Object类中的wait方法相对于Condition类中的await方法
Object类中的wait(long timeout)方法相当于Condition类中的await(long time,TimeUnit unit)方法
Object类中的notify()方法相当于Condition类中的signal()方法
Object类中的notifyAll()方法相当于Condition类中的signalAll()方法
4.1.5 6使用多个Condition实现通知部分线程
Condition对象可以创建多个,每个Condition对象可以唤醒部分指定线程,有助于提升程序的运行效率。
package service03;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private Lock lock = new ReentrantLock();
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition();
public void awaitA() {
lock.lock();
System.out.println("begin awaitA:"+System.currentTimeMillis()+"threadname:"+Thread.currentThread().getName());
try {
conditionA.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void awaitB() {
lock.lock();
System.out.println("begin awaitB:"+System.currentTimeMillis()+"threadname:"+Thread.currentThread().getName());
try {
conditionB.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void signalAll_A() {
try {
lock.lock();
System.out.println("signalAll_A:"+System.currentTimeMillis()+"threadname:"+Thread.currentThread().getName());
conditionA.signalAll();
}finally {
lock.unlock();
}
}
public void signalAll_B() {
try {
lock.lock();
System.out.println("signalAll_B:"+System.currentTimeMillis()+"threadname:"+Thread.currentThread().getName());
conditionA.signalAll();
}finally {
lock.unlock();
}
}
}
Condition对象可以唤醒部分指定的线程,有助于提升程序的执行效率
4.1.6 7实现生产者消费者
解决假死现象:用signalAll方法代替signal方法
4.1.9公平锁与非公平锁
Lock分为公平锁与非公平锁
公平锁:线程获取锁的顺序是按照线程加锁的顺序来分配的
非公平锁:是一种获取锁的抢占机制,是随机获取锁的,这种方式可能导致某些线程一直拿不到锁
http://www.cnblogs.com/java-zhao/p/5131544.html
默认情况下使用非公平锁
4.1.10方法getHoldCount(),getQueueLength()和getWaitQueueLength(Condition condition)的测试
getHoldCount():是查询当前线程保持此锁定的个数,也就是调用lock方法的次数
此处提一下多态https://mp.csdn.net/postedit/82842936
getQueueLength():返回正等待获取此锁定的线程估计数
getWaitQueueLength(Condition condition):返回与此锁定相关的给定条件Condition的线程估计数
4.1.11方法hasQueuedThread(),hasQueuedThreads()和hasWaiters()的测试(均为布尔类型)
boolean hasQueuedThread(Thread thread):查询指定的线程是否正在等待获取此锁定
boolean hasQueuedThreads():查询是否有线程正在等待获取此锁定
boolean hasWaiters(Condition condition):查询是否有线程正在等待与此锁定相关的condition条件
4.1.12方法isFair(),isHeldCurrentThread(),isLocked()的测试
boolean isFair()判断是不是公平锁
boolean isHeldCurrentThread()查询当前线程是否保持此锁定
boolean isLocked()查询此锁定是否由任意线程所保持