各种同步控制工具的使用

Semaphore

概述

共享锁,运行多个线程同时临界区

主要接口

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

概述

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();
                 }
         }

CountDownLatch

概述:

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();
    }
}

CyclicBarrier

概述

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的方法

LockSupport

概述

unpark函数可以先于park调用。比如线程B调用unpark函数,给线程A发了一个“许可”,那么当线程A调用park时,它发现已经有“许可”了,那么它会马上再继续运行。

park和unpark的灵活之处

上面已经提到,unpark函数可以先于park调用,这个正是它们的灵活之处。

一个线程它有可能在别的线程unPark之前,或者之后,或者同时调用了park,那么因为park的特性,它可以不用担心自己的park的时序问题

时间: 2024-08-02 10:33:12

各种同步控制工具的使用的相关文章

各种同步工具使用

1. 如何使用 ReentrantLock 中的 可中断锁防止死锁? 答: 在 执行语句前 加 可中断锁,此时,当被打断时,会抛出 被中断异常,这样就可以解锁. 注意:要外部中断,死锁中的线程不会自己中断 public class ReentrantLockTest { static Lock lock1 = new ReentrantLock(); static Lock lock2 = new ReentrantLock(); public static void main(String[]

并发包(转) http://blog.csdn.net/he90227/article/details/52788981

1. 各种同步控制工具的使用 1.1 ReentrantLock ReentrantLock感觉上是synchronized的增强版,synchronized的特点是使用简单,一切交给JVM去处理,但是功能上是比较薄弱的.在JDK1.5之前,ReentrantLock的性能要好于synchronized,由于对JVM进行了优化,现在的JDK版本中,两者性能是不相上下的.如果是简单的实现,不要刻意去使用ReentrantLock. 相比于synchronized,ReentrantLock在功能上

JDK并发包

1. 各种同步控制工具的使用 1.1 ReentrantLock(重用锁) 1)与synchronized的区别是,它需要手动申请锁与解锁,在 finally 块中释放锁,而synchronized是JVM自动处理的.可控性上ReentrantLock更强. 由于ReentrantLock是重入锁,所以可以反复得到相同的一把锁,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放(重入锁). 注:synchronized 也是可

Java高并发是不是你的菜??

自从JAVA5.0增加了最初由DougLea编写的高质量的.广泛使用的.并发实用程序util.concurrent并变成了JSR-166的新包之后,在Java内置所提供的类库中,就提供了越来越多的并发编程的实用工具类.学习并掌握这些技术对于专注于Java并发编程的开发人员来讲是基本的公里,随着Java版本的不断更新与改进,开发人员可以通过Java新版本所带来的新特性,无需从头重新编写并发程序工具类. 我们该学习Java并发嘛? 我们该如何学习Java并发? CPU这么多核了,我们如何更好的利用?

JDK并发工具之多线程团队协作:同步控制

一.synchronized的功能扩展:重入锁(java.util.concurrent.locks.ReentrantLock) 重入锁可以完全替代synchronized关键字.在JDK 5.0的早期版本中,重入锁的性能远远好于synchronized,但从JDK 6.0开始,JDK在syn-chronized上做了大量的优化,使得两者的性能差距并不大. 01 public class ReenterLock implements Runnable{ 02 public static Ree

操作集合工具类:Collections

Collections是常用的操作Set.List.Map的工具类.提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了将集合对象设置为不可变.对集合对象实现同步控制等方法. reverse 反转: /** * Reverses the order of the elements in the specified list.<p> * * This method runs in linear time. * * @param list the list whose elements a

操作集合的工具类:Collections

数组有工具类 Arrays,集合同样有可操作 Collection 和 Map 的工具类:Collections // Collections 工具类可操作的对象:Collection 和 Map public class TestCollections { public static void main(String[] args) { List list = new ArrayList(); list.add("s"); list.add("b"); list.

Java并发(基础知识)——显示锁和同步工具类

显示锁                                                                                     Lock接口是Java 5.0新增的接口,该接口的定义如下: public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long

操作系统的工具类Collections

一 Collections介绍 1 Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作. 2 Collections还提供了将集合对象设置不可变.对集合对象实现同步控制等方法.   二 排序操作 1 代码示例 Java代码 import java.util.*; public class SortTest { public static void main(String[] args) { Array