java并发包原理及使用场景

java并发包下有很多内置的处理线程安全问题工具类,在集合中就有2种线程同步的类,比如:Vector较ArrayList线程安全,但是效率较低,同样的还有Hashtable和HashMap,在实际项目中常用ArrayList与HashMap,因为前者比重,影响执行效率

  • 以下是java的几种并发包下的使用场景

1.CountDownLatch

CountDownLatch 同步器

1.1 原理:

  • 运行多个或一个线程,等待其他多个或一个线程执行完毕,在执行当前线程
  • java并发包下同步辅助类:定义计数器可以设定个数,每次调用countDown() 计数器中的个数就会减1,当计数器的个数等于0的时候,调用await方法时,就会执行await方法后面的代码,如果计数器个数大于0时,调用await时,是不会执行await后面的代码

1.2 使用场景:

  • 有一个文件,需要2个线程执行读写操作,执行完写的操作才可以读取内容
    实现:使用计数器CountDownLatch,计数器的个数为2,在每个写的线程执行完毕,调用countDown方法,在写的线程后面,调用计数器的await方法,await方法后面执行读线程,这样在读取数据时,可以保证数据的完整性
public class ThreadWrite implements Runnable {
    private Poeple peo;
    private Integer count;
    private CountDownLatch cdl;

    public ThreadWrite(Poeple peo, Integer count,CountDownLatch cdl) {
        this.peo = peo;
        this.count = count;
        this.cdl = cdl;
    }

    @Override
    public void run() {
            System.out.println("ThreadWrite");
            if (count == 0) {
                peo.setName("小明");
                peo.setSex("男");
            } else if (count == 1) {
                peo.setName("小红");
                peo.setSex("女");
            }
            cdl.countDown();//每次执行同步器减一
    }
}

public static void main(String[] args) {
    Poeple peo = new Poeple();
    CountDownLatch cdl = new CountDownLatch(2);//创建同步器,线程个数为2
    new Thread(new ThreadWrite(peo, 1, cdl)).start();
    new Thread(new ThreadWrite(peo, 1, cdl)).start();
    try {
        cdl.await();//等待同步器个数为0,执行后续代码
        new Thread(new ThreadRead(peo)).start();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

2. CyclicBarrier

CyclicBarrier 循环屏障

2.1 原理:

  • 运行多个线程之间相互等待,执行完毕后在执行线程中await后面的代码

2.2 使用场景:

  • 多个线程在执行计算操作,另一个线程需要将计算结果相加,创建一个屏障线程,等待其他线程执行后在执行屏障线程
  • 多个线程中有需要全部执行完,最后执行的代码
/**
 * 写线程
 */
public class ThreadWrite implements Runnable {
    private Poeple peo;
    private Integer count;
    private CyclicBarrier cb;

    public ThreadWrite(Poeple peo, Integer count, CyclicBarrier cb) {
        this.peo = peo;
        this.count = count;
        this.cb = cb;
    }

    @Override
    public void run() {
        System.out.println("ThreadWrite");
        /*循环屏障*/
        try {
            cb.await();//等待线程数等于,CyclicBarrier中parties个数,执行之前所有等待线程await后面的代码
            System.out.println("循环屏障");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}


/**
 * 读取线程
 */
public class ThreadRead implements Runnable {
    private Poeple peo;

    public ThreadRead(Poeple peo) {
        this.peo = peo;
    }

    @Override
    public void run() {
        synchronized (peo) {
            System.out.println("ThreadRead");
            System.out.println(peo.getName());
            System.out.println(peo.getSex());
        }
    }
}

public static void main(String[] args) {
        CyclicBarrier cb = new CyclicBarrier(4);//循环屏障
        System.out.println("当前线程数"+cb.getParties());
        System.out.println("当前线程等待数"+cb.getNumberWaiting());
        Poeple peo = new Poeple();
        int count = 0;
        new Thread(new ThreadWrite(peo, count,cb)).start();
        new Thread(new ThreadWrite(peo, count,cb)).start();
        new Thread(new ThreadWrite(peo, count,cb)).start();
        new Thread(new ThreadWrite(peo, count,cb)).start();
}

3. Semaphore

Semaphore:信号量

3.1 原理:

  • java并发包下,可以处理一个及以上的线程的并发量

3.2 使用场景:

  • 一个楼层,有2个入口,一个入口每次只能进1个人,每次可以进2个人,而使用synchronized,只有一个入口,每次只能进1个人,使用信号量可以提高处理并发的个数
public class ThreadWrite implements Runnable {
    private Poeple peo;
    private Integer count;
    private Semaphore s;
    private List<Poeple> peoList;

    public ThreadWrite(List<Poeple> peoList, Integer count, Semaphore s) {
        this.peoList = peoList;
        this.count = count;
        this.s = s;
    }

    @Override
    public void run() {
        /*信号量*/
        try {
            s.acquire();//获取锁
            System.out.println("ThreadWrite");
            Poeple poeple = new Poeple();
            poeple.setName("name1");
            poeple.setSex("nv");
            peoList.add(poeple);
            System.out.println(Thread.currentThread().getName() + "=========>" + peoList.size());
            s.release();//释放锁
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public static void main(String[] args) {
    Semaphore s = new Semaphore(3);//信号量 同时处理三个线程
    List<Poeple> peo = new ArrayList<>();
    int count = 0;
    for (int i = 0; i < 20; i++) {
        new Thread(new ThreadWrite(peo,count,s),"线程1").start();
        new Thread(new ThreadWrite(peo,count,s),"线程2").start();
        new Thread(new ThreadWrite(peo,count,s),"线程3").start();
    }
}
  • 实体类代码
public class Poeple {
    private Integer id;
    private String name;
    private String sex;

    public Poeple() {
    }

    public Poeple(Integer id, String name, String sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值