ReentrantLock类:
JDK1.5中增加了ReentrantLock类,可以实现线程之间的同步互斥;还具有嗅探锁定,多路分支通知等功能;
使用ReentrantLock实现同步:
public class MyThread extends Thread{
private Service service;
public MyThread(Service service) {
super();
this.service = service;
}
public void run() {
service.testMethod();
}
}
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
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();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
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();
}
}
使用Condition实现等待/通知:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
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) {
// 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();
}
}
}
public class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
public void run() {
service.await();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA ta = new ThreadA(service);
ta.start();
Thread.sleep(3000);
service.signal();
}
}
Object类中的wait()方法 相当于 Condition类中的await()方法;
Object类中的wait(long timeout)方法 相当于 Condition类中的await(long time,TimeUnit unit)方法;
Object类中的notify()方法 相当于 Condition类中的signal()方法;
Object类中的notifyAll()方法 相当于 Condition类中的signalAll()方法;
使用多个Condition实现通知部分线程:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
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 (InterruptedException e) {
// TODO Auto-generated catch block
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 (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());
conditionB.signalAll();
} finally {
lock.unlock();
}
}
}
public class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
public void run() {
service.awaitA();
}
}
public class ThreadB extends Thread{
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
public void run() {
service.awaitB();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ta.start();
ThreadB tb = new ThreadB(service);
tb.setName("B");
tb.start();
Thread.sleep(3000);
service.signalAll_A();
}
}
实现生产者/消费者模式:一对一交替打印
public class ThreadB extends Thread{
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
service.get();
}
}
}
public class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
service.set();
}
}
}
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
try {
lock.lock();
while (hasValue == true) {
condition.await();
}
System.out.println("打印+");
hasValue = true;
condition.signal();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasValue == false) {
condition.await();
}
System.out.println("打印)");
hasValue = false;
condition.signal();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ta.start();
ThreadB tb = new ThreadB(service);
tb.setName("B");
tb.start();
}
}
实现生产者/消费者模式:多对多交替打印
public class ThreadB extends Thread{
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
service.get();
}
}
}
public class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
service.set();
}
}
}
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
private ReentrantLock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
try {
lock.lock();
while (hasValue == true) {
System.out.println("有可能连续+++");
condition.await();
}
System.out.println("打印+");
hasValue = true;
condition.signal();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasValue == false) {
System.out.println("有可能连续)))");
condition.await();
}
System.out.println("打印)");
hasValue = false;
condition.signal();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA[] ta = new ThreadA[10];
ThreadB[] tb = new ThreadB[10];
for (int i = 0; i < 10; i++) {
ta[i] = new ThreadA(service);
tb[i] = new ThreadB(service);
ta[i].start();
tb[i].start();
}
}
}
公平锁与非公平锁:
公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得的FIFO先出先进顺序;而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的就是先来的不一定先得到锁,这个方式可能造成某些线程一直拿不到锁,结果也就是不公平的了。
import java.util.concurrent.locks.ReentrantLock;
public class Service {
private ReentrantLock lock;
public Service(boolean isFair) {
super();
lock = new ReentrantLock(isFair);
}
public void serviceMethod() {
try {
lock.lock();
System.out.println("ThreadName = " + Thread.currentThread().getName() + "获得锁定");
} finally {
lock.unlock();
}
}
}
public class RunFair {
public static void main(String[] args) {
final Service service = new Service(true);
Runnable runnable = new Runnable() {
public void run() {
System.out.println("+线程" + Thread.currentThread().getName() + "运行了");
service.serviceMethod();
}
};
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();
}
}
}
public class RunNoFair {
public static void main(String[] args) {
final Service service = new Service(false);
Runnable runnable = new Runnable() {
public void run() {
System.out.println(")线程" + Thread.currentThread().getName() + "运行了");
service.serviceMethod();
}
};
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();
}
}
}
int getHoldCount() 查询当前线程保持此锁定的个数,也就是调用lock()方法的次数;
int getQueueLength()的作用是返回正等待获取此锁定的线程估计数;
int getWaitQueueLength(Condition condition)作用是返回等待于此锁定相关的给定条件Condition的线程估计数;
boolean hasQueuedThread(Thread thread)的作用是查询指定的线程是否正在等待获取此锁定;
boolean hasQueuedThreads()的作用是查询是否有线程正在等待获取此锁定;
boolean hasWaiters(Condition condition)的作用是查询是否有线程正在等待与此锁定有关的condition条件;
boolean isFair()的作用是判断是不是公平锁;
boolean isHeldByCurrentThread()的作用是查询当前线程是否保持此锁定;
boolean isLocked()的作用是查询此锁定是否由任意线程保持;
void lockInterruptibly()的作用是:如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常;
boolean tryLock()的作用是:仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定;
boolean tryLock(long timeout, TimeUnit unit)的作用是,如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定;
awaitUninterruptibly():
方法condition.awaitUninterruptibly()的使用
线程在调用condition.await()后处于await状态,此时调用thread.interrupt()会报错
但是使用condition.awaitUninterruptibly()后,调用thread.interrupt()则不会报错
awaituntil() :
等到 boolean awaitUntil(Date deadline) throws InterruptedException Date 时间时释放锁。当另一个线程获得了锁没有释放时,虽然awituntil时间已经到了,它没有锁,所以必须等到另一个线程释放锁之后它在执行awaituntil下面的内容。当另一个线程获得锁后,后来已经释放,因为notiyAll 会唤醒所有线程,所以使用awituntil方法的线程也将被唤醒,但如果不使用notifyall来唤醒线程则使用awaitUntil线程还是会等待当前时间到了之后才会被唤醒,因为当它再次得到锁它还是处于等待状态,等到达设定的时间才会被唤醒
使用Condition实现顺序执行:
public class F {
volatile public static int nextPrintWho = 1;
}
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
//按顺序打印
public class Run {
volatile private static int nextPrintWho = 1;
private static ReentrantLock lock = new ReentrantLock();
final private static Condition conditionA = lock.newCondition();
final private static Condition conditionB = lock.newCondition();
final private static Condition conditionC = lock.newCondition();
public static void main(String[] args) {
Thread ta = new Thread() {
public void run() {
try {
lock.lock();
while(nextPrintWho != 1) {
conditionA.await();
}
for(int i = 0; i < 3; i++) {
System.out.println("ThreadA " + (i + 1));
}
nextPrintWho = 2;
conditionB.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread tb = new Thread() {
public void run() {
try {
lock.lock();
while(nextPrintWho != 2) {
conditionB.await();
}
for(int i = 0; i < 3; i++) {
System.out.println("ThreadB " + (i + 1));
}
nextPrintWho = 3;
conditionC.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread tc = new Thread() {
public void run() {
try {
lock.lock();
while(nextPrintWho != 3) {
conditionC.await();
}
for(int i = 0; i < 3; i++) {
System.out.println("ThreadC " + (i + 1));
}
nextPrintWho = 3;
conditionA.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread[] aArray = new Thread[5];
Thread[] bArray = new Thread[5];
Thread[] cArray = new Thread[5];
for (int i = 0; i < 5; i++) {
aArray[i] = new Thread(ta);
bArray[i] = new Thread(tb);
cArray[i] = new Thread(tc);
aArray[i].start();
bArray[i].start();
cArray[i].start();
}
}
}
使用ReentrantReadWriteLock类:
读读 是异步的,非互斥的;读写 写读 写写 都是互斥的;
public class ThreadB extends Thread{
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
public void run() {
service.read();
}
}
public class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
public void run() {
service.read();
}
}
import java.util.concurrent.locks.ReentrantReadWriteLock;;
public class Service {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read() {
try {
try {
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
} finally {
lock.readLock().unlock();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//读读共享
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ThreadB tb = new ThreadB(service);
tb.setName("B");
ta.start();
tb.start();
}
}
public class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
public void run() {
service.write();
}
}
public class ThreadB extends Thread{
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
public void run() {
service.read();
}
}
import java.util.concurrent.locks.ReentrantReadWriteLock;;
public class Service {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void write() {
try {
try {
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
} finally {
lock.writeLock().unlock();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void read() {
try {
try {
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
} finally {
lock.readLock().unlock();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA ta = new ThreadA(service);
ta.setName("A");
ThreadB tb = new ThreadB(service);
tb.setName("B");
ta.start();
tb.start();
}
}