①使用ReentrantLock类
1.使用ReentrandLock实现同步
示例代码:
public class MyService {
private Lock lock = new ReentrantLock();
public void testMethod() {
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1)));
}
lock.unlock();
}
}
class MyThread extends Thread {
private MyService service;
public MyThread(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
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);
a1.start();
a2.start();
a3.start();
a4.start();
}
}
运行结果:
2.使用Condition实现等待/通知
示例代码:
public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await() {
try {
lock.lock();
System.out.println(" await时间为" + System.currentTimeMillis());
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signal() {
try {
lock.lock();
System.out.println("signal时间为" + System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
}
class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.await();
}
}
class Run {
public static void main(String[] args) throws Exception {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.start();
Thread.sleep(3000);
service.signal();
}
}
运行结果:
3.使用多个Condition实现通知部分线程
示例代码:
public class MyService {
private Lock lock = new ReentrantLock();
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition();
public void awaitA() {
try {
lock.lock();
System.out.println("begin awaitA 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
conditionA.await();
System.out.println(" end awaitA 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void awaitB() {
try {
lock.lock();
System.out.println("begin awaitB 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
conditionB.await();
System.out.println(" end awaitB 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void singalAll_A() {
try {
lock.lock();
System.out.println(" signalAll_A 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
conditionA.signalAll();
} finally {
lock.unlock();
}
}
public void singalAll_B() {
try {
lock.lock();
System.out.println(" signalAll_B 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName());
conditionB.signalAll();
} finally {
lock.unlock();
}
}
}
class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.awaitA();
}
}
class ThreadB extends Thread {
private MyService service;
public ThreadB(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.awaitB();
}
}
class Run {
public static void main(String[] args) throws Exception {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
Thread.sleep(3000);
service.singalAll_A();
}
}
运行结果:
4.方法getHoldCount()、getQueueLength()和getWaitQueueLength()测试
--方法getHoldCount()的作用是查询当前线程保持锁定的个数,也就是调用lock方法的次数
示例代码:
public class Service {
private ReentrantLock lock = new ReentrantLock();
public void serviceMethod1() {
try {
lock.lock();
System.out.println("serviceMethod1 getHoldCount=" + lock.getHoldCount());
serviceMethod2();
} finally {
lock.unlock();
}
}
public void serviceMethod2() {
try {
lock.lock();
System.out.println("serviceMethod2 getHoldCount=" + lock.getHoldCount());
} finally {
lock.unlock();
}
}
}
class Run {
public static void main(String args[]) {
Service service = new Service();
service.serviceMethod1();
}
}
运行结果:
--方法getQueueLenght()的作用是返回等待次锁定的线程估计数,比如有5个线程,1个线程首先执行await()方法,那么调用返回值是4
示例代码:
public class Service {
public ReentrantLock lock = new ReentrantLock();
public void serviceMethod1() {
try {
lock.lock();
System.out.println("Threadname=" + Thread.currentThread().getName() + "进入方法! ");
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class Run {
public static void main(String[] args) throws Exception {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.serviceMethod1();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
Thread.sleep(2000);
System.out.println("有线程数:" + service.lock.getQueueLength() + "在等待获取锁!");
}
}
运行结果:
--方法getWaitQueueLength(Condition condition)的作用是返回等待与此所动相关的给定条件Condition的线程估计数
示例代码:
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition newCondtion = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
newCondtion.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void notifyMethod() {
try {
lock.lock();
System.out.println("有" + lock.getWaitQueueLength(newCondtion) + "个线程正在等待newCondition");
newCondtion.signal();
} finally {
lock.unlock();
}
}
}
class Run {
public static void main(String[] args) throws Exception {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
Thread.sleep(2000);
service.notifyMethod();
}
}
运行结果:
--boolean hasQueuedThread(Thread thread) 的作用是查询指定的线程是否正在等待获取此锁定。
示例代码:
public class Service {
public ReentrantLock lock = new ReentrantLock();
public Condition newConditon = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class Run {
public static void main(String[] args) throws Exception {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread threadA = new Thread(runnable);
threadA.start();
Thread.sleep(500);
Thread threadB = new Thread(runnable);
threadB.start();
Thread.sleep(500);
System.out.println(service.lock.hasQueuedThread(threadA));
System.out.println(service.lock.hasQueuedThread(threadB));
System.out.println(service.lock.hasQueuedThreads());
}
}
运行结果:
--boolean hasWaiters(Condition condition)的作用是查询是否有线程正在等待与此锁定有关的condition条件。
示例代码:
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition newCondition = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
newCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void notityMethod() {
try {
lock.lock();
System.out.println("有没有线程正在等待newCondition? " + lock.hasWaiters(newCondition) + " 线程数是多少? " + lock.getWaitQueueLength(newCondition));
newCondition.signal();
} finally {
lock.unlock();
}
}
}
class Run {
public static void main(String[] args) throws Exception {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
Thread.sleep(2000);
service.notityMethod();
}
}
运行结果:
其他:
--方法boolean isFair() 的作用是判断是不是公平锁。
--方法boolean isHeldByCurrentThread()的作用是查询当前线程是否保持锁定。
--方法boolean isLocked() 的作用是查询此锁定是否由任意线程保持。
--方法void lockInterruptibly()作用是:如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常。
--方法boolean tryLock()的作用是,仅在调用时锁定未被另一个线程保持的情况下,才获取该锁。
--方法boolean tryLock(long timeout,TimeUnit unit)的作用是,如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁
参考:《Java多线程编程核心技术》--机械工业出版社 高洪岩 著