- 用 Lock相较于 synchronized优点在于:可以用condition 实现对锁的精确控制
每个condition对象相当于一把锁,可以准确阻塞/ 唤醒特定线程 - 用CountDownLatch控制线程:主要方法countDown(),await();当一个或多个线程调用await时,这些线程会阻塞,其他线程调用countDown会将计数器减1(调用countDown的线程不会阻塞),当计数器的值为0时,因await 阻塞的线程会被唤醒,继续执行
- 用CyclicBarrier控制线程:主要方法await();与CountDownLatch里计数器递减不同,CyclicBarrier是递增,直到超过构造器里设置的参数parties 才唤醒线程
- 用Semaphore控制并发线程数:主要方法acquire(),release();当一个线程调用acquire时,它要么成功获取到信号量(信号量减1),要么等待直到有线程释放信号量或超时;release 会将信号量加1,然后唤醒等待的线程
- 用ReadWriteLock控制线程,保证只能是一个线程进行写操作,可以多个线程进行读操作
1.Lock demo
public class Number {
int num = 1;
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
public void methodA() throws Exception {
lock.lock();
try {
while (num != 1) {
conditionA.await();
}
System.out.println(Thread.currentThread().getName() + "***AAA***");
num = 2;
conditionB.signal();
} finally {
lock.unlock();
}
}
public void methodB() throws Exception {
lock.lock();
try {
while (num != 2) {
conditionB.await();
}
System.out.println(Thread.currentThread().getName() + "***BBB***");
num = 3;
conditionC.signal();
} finally {
lock.unlock();
}
}
public void methodC() throws Exception {
lock.lock();
try {
while (num != 3) {
conditionC.await();
}
System.out.println(Thread.currentThread().getName() + "***CCC***");
num = 1;
conditionA.signal();
} finally {
lock.unlock();
}
}
}
public class LockTest {
public static void main(String[] args) {
Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
number.methodA();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, "R1").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
number.methodB();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, "R2").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
number.methodC();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, "R3").start();
}
}
- CountDownLatch demo
public class Demo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDown=new CountDownLatch(5);
for (int i = 1; i <= 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + "结束");
countDown.countDown();
}
}).start();
}
countDown.await();
System.out.println(Thread.currentThread().getName() + " " + "结束");
}
}
- CyclicBarrier Demo
public class Demo {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.out.println("5个线程已结束");
}
});
for (int i = 1; i <= 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + "结束");
try {
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
- Semaphore Demo
public class Demo {
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " " + "占用");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + " " + "释放");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
}
}).start();
}
}
}
- ReadWriteLock demo
public class Number {
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void write() {
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " " + "开始写入");
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + "写入完成");
} finally {
readWriteLock.writeLock().unlock();
}
}
public void read() {
readWriteLock.readLock().lock();
try{
System.out.println(Thread.currentThread().getName() + " " + "开始读入");
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + "读入完成");
}finally {
readWriteLock.readLock().unlock();
}
}
}
public class Demo {
public static void main(String[] args) throws InterruptedException {
Number num = new Number();
for (int i=1;i<=5;i++){
new Thread(new Runnable() {
@Override
public void run() {
num.read();
}
}).start();
}
for (int i=1;i<=5;i++){
new Thread(new Runnable() {
@Override
public void run() {
num.write();
}
}).start();
}
}
}