并发工具类【线程安全相关的类】

1.Hashtable和ConcurrentHashMap

Hashtable:哈希表结构(数组+链表),线程安全的(同步代码块,效率低)
ConcurrentHashMap:
jdk7:采用Segment数组[不会扩容] + HashEntry[二次哈希计算存入的位置,可扩容],线程安全(synchronized)
jdk8:哈希表结构(数组+链表+红黑树),线程安全的(synchronized+CAS算法,效率高)
【注:使用线程不安全的类可能会出现赋值为null的情况】

public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        //Hashtable<String, String> hsTable = new Hashtable<>();
        ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 25; i++) {
                concurrentHashMap.put(i + "", i + "");
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 25; i < 51; i++) {
                concurrentHashMap.put(i + "", i + "");
            }
        });
        thread1.start();
        thread2.start();
        System.out.println("--------------------");
        //为了两条线程的数据都添加完毕
        Thread.sleep(1000);
        //打印集合的所有值
        for (int i = 0; i < 51; i++) {
            System.out.println(concurrentHashMap.get(i + ""));
        }
    }
}

打印结果:
--------------------------------------------------------------------------------------
0
......
49
50
2.CountDownLatch

孩子吃完饺子,妈妈收拾碗筷【使用场景:当需要某一个线程在其他线程执行完毕之后才执行】
原理:创建CountDownLatch的对象,参数为等待线程的数量, 并定义了一个计数器,初始值为参数的值

//CountDownLatch 并发工具类
public class Demo {
    public static void main(String[] args) {
        //创建CountDownLatch的对象,参数为等待线程的数量
        //并定义了一个计数器,初始值为参数的值【参数为多少则几条线程结束后才执行】
        CountDownLatch countDownLatch = new CountDownLatch(1);
        //countDownLatch传递到4个线程时,它们则共用一个计数器
        MotherThread motherThread = new MotherThread(countDownLatch,"妈妈---");
        ChildThread1 childThread1 = new ChildThread1(countDownLatch,"小刚---");
        //ChildThread2 childThread2 = new ChildThread2(countDownLatch,"小明---");
        //ChildThread3 childThread3 = new ChildThread3(countDownLatch,"小红---");
        motherThread.start();
        childThread1.start();
        //childThread2.start();
        //childThread3.start();
    }
}

//ChildThread1 孩子1线程,同理其他孩子线程与之一致,可复制添加
public class ChildThread1 extends Thread {
    private CountDownLatch countDownLatch;

    public ChildThread1(CountDownLatch countDownLatch, String s) {
        this.countDownLatch = countDownLatch;
        this.setName(s);
    }

    @Override
    public void run() {
        //1.吃饺子
        for (int i = 1; i <= 3; i++) {
            System.out.println(Thread.currentThread().getName() + "在吃" + i + "个饺子");
        }
        //2.吃完说一声
        //每一次countDown方法后,count--;
        countDownLatch.countDown();
    }
}

//妈妈线程
public class MotherThread extends Thread{
    private CountDownLatch countDownLatch;
    public MotherThread(CountDownLatch countDownLatch, String s) {
        this.countDownLatch=countDownLatch;
    }

    @Override
    public void run() {
        try {
            //1.等待
            //当计数器变为0时,会自动唤醒等待的线程
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //2.收拾碗筷
        System.out.println("妈妈正在收拾碗筷");
    }
}

打印结果:
--------------------------------------------------------------------------------------
小刚---在吃1个饺子
小刚---在吃2个饺子
小刚---在吃3个饺子
妈妈正在收拾碗筷
3.Semaphore管理员对象

用来控制正在执行的线程数量

//Semaphore管理员对象【用来控制正在执行的线程数量】
public class Demo1 {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        //开启100条线程
        for (int i = 0; i < 4; i++) {
            new Thread(myRunnable).start();
        }
    }
}

//具体实现类
public class MyRunnable implements Runnable {
    //1.创建Semaphore对象,参数为通行证数量
    Semaphore semaphore =new Semaphore(2);
    @Override
    public void run() {
        try {
            //2.获得通行证
            semaphore.acquire();
            //3.开始行驶
            System.out.println("获得了通行证开始通行");
            //4.归还通行证
            System.out.println("归还通信证");
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

打印结果:
--------------------------------------------------------------------------------------
获得了通行证开始通行
归还通信证
获得了通行证开始通行
归还通信证
获得了通行证开始通行
归还通信证
获得了通行证开始通行
归还通信证
4.其他线程安全类

StringBuilder和StringBuffer
StringBuilder: 线程不安全的(效率高)
StringBuffer: 线程安全的(效率低)
安全的原因是因为其内部方法都有锁
ArrayList和Vector
ArrayList: 数组结构,线程不安全(效率高)
Vector: 数组结构,线程安全的(效率低)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陪雨岁岁年年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值