黑马程序员技术交流社区

标题: 多线程下的并发包:这些面试必问的,你都知道吗? [打印本页]

作者: 逆风TO    时间: 2020-4-8 14:10
标题: 多线程下的并发包:这些面试必问的,你都知道吗?
文章目录
ConcurrentHashMap
CountDownLatch
CyclicBarrier
Semaphore
Exchanger
在JDK的并发包里提供了几个非常有用的并发容器和并发工具类,供我们在多线程开发中进行使用。

并发包的来历:
在实际开发中如果不需要考虑线程安全问题,大家不需要做线程安全,因为如果做了反而性能不好!
但是开发中有很多业务是需要考虑线程安全问题的,此时就必须考虑了。否则业务出现问题。
Java为很多业务场景提供了性能优异,且线程安全的并发包,程序员可以选择使用!
ConcurrentHashMap
为什么要使用ConcurrentHashMap:
HashMap线程不安全,会导致数据错乱
使用线程安全的Hashtable效率低下
基于以上两个原因,便有了ConcurrentHashMap的闪亮登场机会。
HashMap线程不安全演示
[Java] 纯文本查看 复制代码
public class ConcurrentHashMapDemo {
    // 定义一个静态的HashMap集合,只有一个容器。
     public static Map<String,String> map = new HashMap<>();
      //public static Map<String,String> map = new Hashtable<>();
    //public static Map<String,String> map = new ConcurrentHashMap<>();

    public static void main(String[] args) throws Exception {
        // HashMap线程不安全演示。
        // 需求:多个线程同时往HashMap容器中存入数据会出现安全问题。
        // 具体需求:提供2个线程分别给map集合加入50万个数据!
        Runnable target = new AddMapDataThread();
        Thread t1 = new Thread(target,"线程1");
        Thread t2 = new Thread(target,"线程2");
        t1.start();//让t1跑完,主线程不能抢t1的cpu,但是t2抢t1的cpu
        t2.start();//让t2跑完,主线程不能抢t1的cpu,但是t1抢t2的cpu

        t1.join();
        t2.join();

        //休息10秒,确保两个线程执行完毕
        //Thread.sleep(1000 * 4);
        //打印集合大小
        System.out.println("Map大小:" + map.size());
    }
}

class AddMapDataThread implements Runnable{
    @Override
    public void run() {
        for(int i = 1 ; i <= 500000 ; i++ ){
            ConcurrentHashMapDemo.map.put(Thread.currentThread().getName()+"键:"+i ,"值"+i);
        }
    }
}

说明:两个线程分别向同一个map中写入50000个键值对,最后map的size应为:100000,但多运行几次会发现有以下几种错误:
错误结果

假死

异常报错

Hashtable保证的线程安全,但是效率低。
HashTable效率低下原因:
public synchronized V put(K key, V value)
public synchronized V get(Object key)

HashTable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下HashTable的效率非常低下。因为当一个线程访问HashTable的同步方法,其他线程也访问HashTable的同步方法时,会进入阻塞状态。如线程1使用put进行元素添加,线程2不但不能使用put方法添加元素,也不能使用get方法来获取元素,所以竞争越激烈效率越低。

ConcurrentHashMap仍能保证结果正确,而且提高了效率。
ConcurrentHashMap高效的原因:CAS + 局部(synchronized)锁定分段式锁

小结:
HashMap是线程不安全的。
Hashtable线程安全基于synchronized,综合性能差,被淘汰了。
ConcurrentHashMap:线程安全的,分段式锁,综合性能最好,线程安全开发中推荐使用
CountDownLatch
CountDownLatch允许一个或多个线程等待其他线程完成操作,再执行自己。

例如:线程1要执行打印:A和C,线程2要执行打印:B,但线程1在打印A后,要线程2打印B之后才能打印C,所以:线程1在打印A后,必须等待线程2打印完B之后才能继续执行。
CountDownLatch构造方法:
public CountDownLatch(int count)// 初始化一个指定计数器的CountDownLatch对象

CountDownLatch重要方法:
public void await() throws InterruptedException// 让当前线程等待
public void countDown()        // 计数器进行减1

代码示例
[Java] 纯文本查看 复制代码
public class CountDownLatchDemo {
    public static void main(String[] args) {
        //创建1个计数器:用来控制 A , B线程的执行流程的。
        CountDownLatch down = new CountDownLatch(1);

        new ThreadA(down).start();
        new ThreadB(down).start();
    }
}

class ThreadA extends Thread{
    private CountDownLatch down;
    public ThreadA(CountDownLatch down){
        this.down = down;
    }
    @Override
    public void run() {
        System.out.println("A");
        try {
            down.await(); // A线程你进入等待,让B线程执行自己!
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("C");
    }
}

class ThreadB extends Thread{
    private CountDownLatch down;
    public ThreadB(CountDownLatch down){
        this.down = down;
    }
    @Override
    public void run() {
        System.out.println("B");
        down.countDown(); // 这里相当于是-1,代表自己执行完毕了。A线程被唤醒!!
    }
}

结果:会保证按:A B C的顺序打印。

说明:
CountDownLatch是通过一个计数器来实现的,每当一个线程完成了自己的任务后,可以调用countDown()方法让计数器-1,当计数器到达0时,调用CountDownLatch。
await()方法的线程阻塞状态解除,继续执行。
CyclicBarrier
CyclicBarrier的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
CyclicBarrier构造方法:
public CyclicBarrier(int parties, Runnable barrierAction)
// 用于在线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景

CyclicBarrier重要方法:
public int await()// 每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞

使用场景

使用场景:CyclicBarrier可以用于多线程计算数据,最后合并计算结果的场景。
需求:使用两个线程读取2个文件中的数据,当两个文件中的数据都读取完毕以后,进行数据的汇总操作。
Semaphore
Semaphore(发信号)的主要作用是控制线程的并发数量。
synchronized可以起到"锁"的作用,但某个时间段内,只能有一个线程允许执行。
Semaphore可以设置同时允许几个线程执行。
Semaphore字面意思是信号量的意思,它的作用是控制访问特定资源的线程数目。
Semaphore构造方法:
public Semaphore(int permits)                                                permits 表示许可线程的数量
public Semaphore(int permits, boolean fair)                        fair 表示公平性,如果这个设为 true 的话,下次执行的线程会是等待最久的线程


Semaphore重要方法:
public void acquire() throws InterruptedException        表示获取许可
public void release()                                                                release() 表示释放许可


Exchanger
Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。
这两个线程通过exchange方法交换数据,如果第一个线程先执行exchange()方法,它会一直等待第二个线程也执行exchange方法,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。
Exchanger构造方法:
public Exchanger()
1
Exchanger重要方法:
public V exchange(V x)

使用场景:可以做数据校对工作
需求:比如我们需要将纸制银行流水通过人工的方式录入成电子银行流水。为了避免错误,采用AB岗两人进行录入,录入到两个文件中,系统需要加载这两个文件,并对两个文件数据进行校对,看看是否录入一致.
你知道的越多,你不知道的越多。
有道无术,术尚可求,有术无道,止于术。
如有其它问题,欢迎大家留言,我们一起讨论,一起学习,一起进步




作者: 逆风TO    时间: 2020-4-20 10:00
感谢分享哦~
作者: 大安    时间: 2020-4-20 11:04

感谢分享哦~
作者: 大安    时间: 2020-4-20 11:05

感谢分享哦~
作者: hongping    时间: 2020-4-20 11:21

感谢分享哦~
作者: 孙丽    时间: 2020-5-4 11:41
6666666666666666666666
作者: 王锦    时间: 2020-5-4 11:46
66666666666666666666
作者: zhaosongzhi    时间: 2020-5-4 11:49
作者棒棒哒
作者: 我是小圆圆    时间: 2020-5-4 11:50
感谢分享哦~
作者: zhaosongzhi    时间: 2020-5-4 11:57
作者棒棒哒
作者: 竹竹竹竹    时间: 2020-5-4 12:04
感谢分享
作者: zhaosongzhi    时间: 2020-5-4 12:06
作者棒棒哒
作者: zhaosongzhi    时间: 2020-5-4 12:15
作者棒棒哒
作者: 霍尔    时间: 2020-5-4 12:18
66666666666666666
作者: zhaosongzhi    时间: 2020-5-4 12:23
作者棒棒哒
作者: zhaosongzhi    时间: 2020-5-4 12:32
作者棒棒哒
作者: zhaosongzhi    时间: 2020-5-4 12:40
作者棒棒哒
作者: zhaosongzhi    时间: 2020-5-4 12:49
作者棒棒哒
作者: 零度☆黎明    时间: 2020-5-4 13:06
棒棒哒 ..................... ..................
作者: zplxwl    时间: 2020-5-4 13:26
很不错哦!!!
作者: 半个程序员    时间: 2020-5-4 13:46
感谢分享哦~
作者: 马洁    时间: 2020-5-4 14:20

作者: hello!!!    时间: 2020-5-4 14:21

作者: sdjadyhm    时间: 2020-5-4 15:27

感谢分享哟~  棒棒哒加油~~
作者: 耙丫丫    时间: 2020-5-4 16:10
6666666666666666666666
作者: 哦嗨呦    时间: 2020-5-4 16:55
好人一生平安
作者: 黑马程序员啊    时间: 2020-5-4 18:34
6666666666666666666
作者: manyihang    时间: 2020-5-4 21:36
666666666666666666666
作者: 逆风TO    时间: 2020-5-5 09:48
感谢分享呀~
作者: lvxinvip    时间: 2020-5-5 10:03

作者: hongping    时间: 2020-5-5 10:05
感谢分享呀~
作者: hongping    时间: 2020-5-5 10:26

666666666666666
作者: mydorling11    时间: 2020-5-5 11:20
66666666666666666666666666666666666666666
作者: 1467584    时间: 2020-5-5 15:28
66666666666666666666
作者: 章鱼顶呱呱    时间: 2020-5-5 15:33
66666666666666666666
作者: yujq    时间: 2020-5-5 21:06
66666666666666666
作者: daoqin    时间: 2020-5-6 09:33
感谢分享~加油哦~
作者: 大安    时间: 2020-5-6 09:50

感谢分享
作者: 咨询部王丹    时间: 2020-5-6 09:57
感谢分享6666666666666
作者: 大安    时间: 2020-5-6 10:02

感谢分享哦~
作者: kdhdjdj    时间: 2020-5-6 14:31

作者棒棒哒
作者: 影@子~    时间: 2020-5-7 09:52
感谢分享
作者: 大智叔叔    时间: 2020-5-7 15:37

很不错哦!!!
作者: 你不爱我    时间: 2020-5-7 16:12
感谢分享~~                     
作者: 举个栗子    时间: 2020-5-7 16:18
66666666666666666666666666
作者: 小公举    时间: 2020-5-7 17:27
很实用感谢感谢
作者: 我爱我1022    时间: 2020-5-7 17:45

作者: 王微    时间: 2020-5-7 17:53
感谢分享哦~
作者: Emmmmm~    时间: 2020-5-8 09:48

666666666666666666
作者: jsnoob    时间: 2020-5-8 10:01
加油加油加油!!!
作者: lzq123    时间: 2020-5-8 10:05
66666666666666666666666666666
作者: 雨落轻舟    时间: 2020-5-8 11:52
牛人66666666666666666666
作者: 素问    时间: 2020-5-8 13:23
感谢分享,加油~~~~!!!!
作者: 殷凯老师    时间: 2020-5-8 14:29
666666666666666666
作者: 逆风TO    时间: 2020-5-11 17:40
逆风TO 发表于 2020-4-20 10:00
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
大安 发表于 2020-4-20 11:04
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
zhaosongzhi 发表于 2020-5-4 12:32
作者棒棒哒

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
zhaosongzhi 发表于 2020-5-4 12:40
作者棒棒哒

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
zhaosongzhi 发表于 2020-5-4 12:40
作者棒棒哒

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
竹竹竹竹 发表于 2020-5-4 12:04
感谢分享

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
zhaosongzhi 发表于 2020-5-4 11:57
作者棒棒哒

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
竹竹竹竹 发表于 2020-5-4 12:04
感谢分享

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
hongping 发表于 2020-4-20 11:21
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:40
hongping 发表于 2020-4-20 11:21
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:41
竹竹竹竹 发表于 2020-5-4 12:04
感谢分享

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:41
大安 发表于 2020-4-20 11:04
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:41
大安 发表于 2020-4-20 11:05
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:41
半个程序员 发表于 2020-5-4 13:46
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
咨询部王丹 发表于 2020-5-6 09:57
感谢分享6666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
大安 发表于 2020-5-6 10:02
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
daoqin 发表于 2020-5-6 09:33
感谢分享~加油哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
hello!!! 发表于 2020-5-4 14:21

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
mydorling11 发表于 2020-5-5 11:20
66666666666666666666666666666666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
lvxinvip 发表于 2020-5-5 10:03

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
hongping 发表于 2020-5-5 10:26
666666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
mydorling11 发表于 2020-5-5 11:20
66666666666666666666666666666666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
hongping 发表于 2020-5-5 10:26
666666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
1467584 发表于 2020-5-5 15:28
66666666666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
哦嗨呦 发表于 2020-5-4 16:55
好人一生平安

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
逆风TO 发表于 2020-5-5 09:48
感谢分享呀~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
lvxinvip 发表于 2020-5-5 10:03

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
kdhdjdj 发表于 2020-5-6 14:31
作者棒棒哒

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
逆风TO 发表于 2020-5-11 17:40
努力呀,加油呀

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
逆风TO 发表于 2020-5-11 17:40
努力呀,加油呀

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:42
逆风TO 发表于 2020-5-11 17:40
努力呀,加油呀

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
逆风TO 发表于 2020-5-11 17:40
努力呀,加油呀

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
逆风TO 发表于 2020-5-11 17:42
努力呀,加油呀

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
kdhdjdj 发表于 2020-5-6 14:31
作者棒棒哒

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
逆风TO 发表于 2020-5-11 17:40
努力呀,加油呀

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
逆风TO 发表于 2020-5-11 17:40
努力呀,加油呀

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
半个程序员 发表于 2020-5-4 13:46
感谢分享哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
马洁 发表于 2020-5-4 14:20

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
yujq 发表于 2020-5-5 21:06
66666666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
daoqin 发表于 2020-5-6 09:33
感谢分享~加油哦~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
咨询部王丹 发表于 2020-5-6 09:57
感谢分享6666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
yujq 发表于 2020-5-5 21:06
66666666666666666

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
hongping 发表于 2020-5-5 10:05
感谢分享呀~

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
哦嗨呦 发表于 2020-5-4 16:55
好人一生平安

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
马洁 发表于 2020-5-4 14:20

努力呀,加油呀
作者: 逆风TO    时间: 2020-5-11 17:43
hello!!! 发表于 2020-5-4 14:21

努力呀,加油呀




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2