加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

LINUX实战:各种同步控制工具的使用

发布时间:2020-12-13 17:28:19 所属栏目:Linux 来源:网络整理
导读:《LINUX实战:各种同步控制工具的使用》要点: 本文介绍了LINUX实战:各种同步控制工具的使用,希望对您有用。如果有疑问,可以联系我们。 Semaphore 概述 共享锁,运行多个线程同时临界区 主要接口 public void acquire() public void acquireUninterruptibl

《LINUX实战:各种同步控制工具的使用》要点:
本文介绍了LINUX实战:各种同步控制工具的使用,希望对您有用。如果有疑问,可以联系我们。

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

概述

ReadWriteLockJDK5中提供的写分别

主要使用

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的时序问题

本文永远更新链接地址

欢迎参与《LINUX实战:各种同步控制工具的使用》讨论,分享您的想法,编程之家PHP学院为您提供专业教程。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读