共享锁,运行多个线程同时临界区ide
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()这个方法,能够被别的线程进行调用,ui
通常使用acquire() 与release() 这个之间的代码只能有固定数量的线程存在,固然这种是当前线程进行获取和释放this
ReadWriteLock是JDK5中提供的读写分离锁
spa
读-读不互斥:读读之间不阻塞。
读-写互斥:读阻塞写,写也会阻塞读。
写-写互斥:写写阻塞。
线程
private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
blog
这个类若是没有写锁的状况下,读是无阻塞的,在必定程度上提升了程序的执行效率。接口
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(); //主线等待指定数量的子线程完成做业,当全部子线程完成以后,主线程自动激活执行
get
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的方法it
unpark函数能够先于park调用。好比线程B调用unpark函数,给线程A发了一个“许可”,那么当线程A调用park时,它发现已经有“许可”了,那么它会立刻再继续运行。
上面已经提到,unpark函数能够先于park调用,这个正是它们的灵活之处。
一个线程它有可能在别的线程unPark以前,或者以后,或者同时调用了park,那么由于park的特性,它能够不用担忧本身的park的时序问题