共享锁,运行多个线程同时临界区
public void acquire()public void acquireUninterruptibly()public boolean tryAcquire()public boolean tryAcquire(long timeout, TimeUnit unit)public void release()
- public class SemaphoreDemo {
- private static final int THREAD_COUNT = 3;
- private static ExecutorService threadPool = Executors
- .newFixedThreadPool(THREAD_COUNT);
- private static Semaphore s = new Semaphore(1);
- public static void main(String[] args) {
- for(int i=0;i<3;i++)
- {
- threadPool.execute(new Runnable() {
- @Override
- public void run() {
- try {
- System.out.println(Thread.currentThread().getName()+"start data");
- Thread.sleep(2000);
- s.acquire();
- Thread.sleep(1000);
- System.out.println(Thread.currentThread().getName()+"save data");
- s.release();
- System.out.println(Thread.currentThread().getName()+"release data");
- Thread.sleep(2000);
- System.out.println(Thread.currentThread().getName()+"end data");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- });
- }
- threadPool.shutdown();
- }
- }
最后得出一个比较有意思的结论:Semaphore 像是一个共享的屋子,这个屋子里面只能有一定的人数,这个人数是所有人可以看到的,甚至与 release() 这个方法,可以被别的线程进行调用,
一般使用 acquire() 与 release() 这个之间的代码只能有固定数量的线程存在,当然这种是当前线程进行获取和释放
ReadWriteLock 是 JDK5 中提供的读写分离锁
读 - 读不互斥:读读之间不阻塞。读 - 写互斥:读阻塞写,写也会阻塞读。写 - 写互斥:写写阻塞。
private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();private static Lock readLock = readWriteLock.readLock();private static Lock writeLock = readWriteLock.writeLock();
这个类如果没有写锁的情况下,读是无阻塞的, 在一定程度上提高了程序的执行效率。
- public void run() {
- //isRead自定义变量(判断这个线程是读还是写)
- if (isRead) {
- //获取读锁
- myLock.readLock().lock();
- System.out.println("读");
- //释放读锁
- myLock.readLock().unlock();
- } else {
- //获取写锁
- myLock.writeLock().lock();
- //执行现金业务
- System.out.println("写");
- //释放写锁
- myLock.writeLock().unlock();
- }
- }
static final CountDownLatch end = new CountDownLatch(10);end.countDown(); // 这个方法是子线程作完作业之后,调用的 end.await(); // 主线等待指定数量的子线程完成作业,当所有子线程完成之后,主线程自动激活执行
- public class CountDownLatchDemo {
- private static CountDownLatch countDownLatch=new CountDownLatch(10);
- public static void main(String[] args) {
- for(int i=0;i<10;i++)
- {
- new Thread(new Runnable() {
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName()+"work");
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- countDownLatch.countDown();
- }
- }).start();
- }
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- countDownLatch.await();
- System.out.println(Thread.currentThread().getName()+"主线程start");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"main1").start();
- }
- }
- public class CyclicBarrierDemo {
- public static class Soldier implements Runnable{
- private String name;
- private final CyclicBarrier cyclicBarrier;
- public Soldier(String name,CyclicBarrier c) {
- this.name = name;
- this.cyclicBarrier=c;
- }
- @Override
- public void run() {
- try{
- //等待所有士兵到齐
- System.out.println(name +"报道");
- cyclicBarrier.await();
- dowork();
- //等待所有士兵完成工作
- cyclicBarrier.await();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- public void dowork()
- {
- System.out.println(name +"完成任务");
- }
- }
- public static class BarrierRun implements Runnable{
- boolean flag;
- int number;
- public BarrierRun(boolean flag, int number) {
- this.flag = flag;
- this.number = number;
- }
- @Override
- public void run() {
- if(!flag)
- {
- System.out.println("士兵集合完毕");
- flag=true;
- System.out.println("开始执行任务");
- }
- else{
- System.out.println("任务完成");
- }
- }
- }
- public static void main(String[] args) {
- final int N =10;
- CyclicBarrier barrier =new CyclicBarrier(N,new BarrierRun(false,N));
- System.out.println("集合队伍");
- for(int i=0;i<N;i++)
- {
- new Thread(new Soldier("士兵"+i,barrier)).start();
- }
- }
- }
每次 CyclicBarrier 调用 await() 方法之后,都会等待所有的子线程,之后执行 CyclicBarrier 的 Runnable 的方法
unpark 函数可以先于 park 调用。比如线程 B 调用 unpark 函数,给线程 A 发了一个 "许可",那么当线程 A 调用 park 时,它发现已经有 "许可" 了,那么它会马上再继续运行。
上面已经提到,unpark 函数可以先于 park 调用,这个正是它们的灵活之处。
一个线程它有可能在别的线程 unPark 之前,或者之后,或者同时调用了 park,那么因为 park 的特性,它可以不用担心自己的 park 的时序问题
来源: http://www.cnblogs.com/lizhiyan-world/p/6911082.html