Lock是JDK1.5提供的一个表示锁的新接口
提供了用于加锁的方法lock()以及解锁的方法unLock();
相对传统的synchronized而言,Lock提供有公平和非公平策略,所以Lock的应用更加灵活。
例如一个整数在多线程下的自增
代码语言:javascript复制package com.jmy.concurrent;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo {
static int i;
public static void main(String[] args) {
Lock lock = new ReentrantLock();
new Thread(new AddDemo(lock)).start();
new Thread(new AddDemo(lock)).start();
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
class AddDemo implements Runnable {
private Lock lock;
public AddDemo(Lock lock) {
this.lock = lock;
}
@Override
public void run() {
for (int i = ; i < ; i ) {
lock.lock();
LockDemo.i ;
lock.unlock();
}
}
}
代码语言:javascript复制公平和非公平策略
公平策略:在被抢占的资源前加一个工作队列(阻塞队列),线程 抢占的为工作队列的入队顺序,相对公平。
非公平策略:加锁时不考虑队列,线程直接抢占资源,效率较高。 synchronized是非公评策略
Lock默认是非公平策略,可以手动设置为公平策略(构造方法提供Boolean参数)
代码语言:javascript复制读写锁
读写锁分为读锁和写锁
读锁:允许多个线程读取,但是不允许线程写入
写锁:允许一个线程写入,但是不允许线程读取
代码语言:javascript复制CountDownLatch
CountDownLatch被称为闭锁或者线程递减锁 用于线程计数,当计数技术后才会执行其他线程。 例如一场面试要等面试官到场才可以开始
代码语言:javascript复制package com.jmy.concurrent;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch();
new Thread(new Teacher(countDownLatch)).start();
new Thread(new Student(countDownLatch)).start();
new Thread(new Student(countDownLatch)).start();
new Thread(new Student(countDownLatch)).start();
new Thread(new Student(countDownLatch)).start();
countDownLatch.await(); // 线程阻塞
System.out.println("考试开始!");
}
}
class Teacher implements Runnable{
private CountDownLatch countDownLatch;
public Teacher(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("面试官到达考场!");
countDownLatch.countDown(); // 线程计数减一
}
}
class Student implements Runnable {
private CountDownLatch countDownLatch;
public Student(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("面试者到达考场!");
countDownLatch.countDown();
}
}
代码语言:javascript复制CyclicBarrier
CyclicBarrier被称为栅栏
现场所有线程都到达指定地点之后在一起执行
例如所有运动员都到达起跑线发令枪响之后一起跑了出去
代码语言:javascript复制package com.jmy.concurrent;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch();
CyclicBarrier barrier = new CyclicBarrier();
new Thread(new Sporter(barrier,countDownLatch)).start();
new Thread(new Sporter(barrier,countDownLatch)).start();
new Thread(new Sporter(barrier,countDownLatch)).start();
new Thread(new Sporter(barrier,countDownLatch)).start();
countDownLatch.await();
System.out.println("枪响啦!");
}
}
class Sporter implements Runnable {
private CyclicBarrier barrier;
private CountDownLatch countDownLatch;
public Sporter(CyclicBarrier barrier, CountDownLatch countDownLatch) {
this.barrier = barrier;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
countDownLatch.countDown();
System.out.println("运动员到达起点");
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("运动员跑了出去!");
}
}
代码语言:javascript复制Exchanger<T>
用于两个线程进行信息或者数据的交换
泛型表示要交换的信息类型
就是这么简单。。