并发包ConcurrentHashMap CountDownLatch CyclicBarrier Semaphore Exchanger

并发包

ConcurrentHashMap

HashMap是线程不安全的,性能好

Hashtable是线程安全的Map集合,性能较差,已淘汰,整个数组全锁

ConcurrentHashMap线程安全,性能好,只锁自己操作的元素位置

public static Map<String, String> maps = new ConcurrentHashMap<>();

public static void main() {
    Runnable target = new MyRunnable();
    Thread t1 = new Thread(target, "线程1");
    Thread t2 = new Thread(target, "线程2");
    t1.start();
    t2.start();
    
    t1.join(); // t1执行完
    t2.join(); // t2执行完
    
    // HashMap得到的size不到1000000
    System.out.println(maps.size());
}
class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i  = 1; i <= 500000; i++) {
            Demo.maps.put(Thread.currentThread().getName() + i,
                          Thread.currentThread().getName());
        }
    }
}

CountDownLatch

需求:

​ A线程,打印A、C

​ B线程,打印B

​ 当A线程先执行时,打印 A、B、C

public class CountDownLatchDemo {
    public static void main() {
        // 监督者 等待1步
        CountDownLatch c = new CountDownLatch(1);
        new ThreadA(c).start();
        new ThreadB(c).start();
    }
}
class ThreadA extends Thread {
    private CountDownLatch c;
    public ThreadA(CountDownLatch c) {
        this.c = c;
    }
    
    @Override
    public void run() {
        System.out.println("A");
        // 开始等待
        c.await();
        System.out.println("C");
    }
}
class ThreadB extends Thread {
    private CountDownLatch c;
    public ThreadB(CountDownLatch c) {
        this.c = c;
    }
    
    @Override
    public void run() {
        System.out.println("B");
        // 计数器减1
        c.countDown();
    }
}

CyclicBarrier

多线程计算数据,最后合并计算结果

循环屏障

某个线程等待其他线程执行完毕才执行

五个员工都到齐,才执行开会的操作

class EmployeeThread extends Thread {
    private CyclicBarrier c;
    public EmployeeThread(String name, CyclicBarrier c) {
        super(name);
        this.c = c;
    }
    
    @Override
    public void run() {
        // 模拟员工正在进入会议室
        Thread.sleep(3000);
        // 告诉屏障自己已到达:障碍解除(被回收)
        c.await();
    }
}

class Meeting implements Runnable {
    @Override
    public void run() {
        System.out.println("开会!");
    }
}

public class MainDemo {
    public static void main() {
        // 5个员工开一次会
        // 创建一个循环屏障,等5个线程执行完毕,触发一次开会任务
        CyclicBarrier c = new CyclicBarrier(5, new Meeting());
        for (int i = 0; i < 5; i++) {
            new EmployeeThread("员工" + i, c).start();
        }
        
    }
}

Semaphore

控制线程并发的数量(1000万)

锁可以同时进三个线程

class Servie {
    // 相当于是锁,用于控制流量,但会有安全问题
    // 同时存在3个线程时,一个刚走,另一个就会进来,始终保持3个线程
    private Semaphore semaphore = new Semaphore(1);
    public void login() {
        // 上锁
        semaphore.acquire();
        System.out.println("登录");
        // 解锁
        semaphore.release();
    }
}
class MyThread extends Thread {
    private Service service;
    public MyThread(Service service) {
        this.service = service;
    }
    
    @Override
    public void run() {
        service.login();
    }
}
public class Test {
    public static void main() {
        Service service = new Service();
        for(int i = 0; i < 5; i++) {
            Thread a = new MyThread(service);
            a.start();
        }
    }
}

Exchanger

可以做数据校对工作(两个人录同一份数据)

线程间的数据交换,不是等待和唤醒(没有交流数据)

同步交换数据,媒婆

public class Test {
    public static void main() {
		Exchanger<String> exchanger = new Exchanger();
        new Thread(new Boy(exchanger));
        new Thread(new Girl(exchanger));
    }
}
class Boy extends Thread {
    private Exchanger<String> exchanger;
    public Boy(Exchanger exchanger) {
        this.exchager = exchanger;
    }
    @Override
    public void run() {
        System.out.println("boy准备好的数据");
        // 收到girl的数据(没收到会在这里等待)
        // 可设置等待girl的时间,等不到就抛异常TimeoutException延时异常
        String girlData = exchanger.exchange();
    }
}
class Girl extends Thread {
    private Exchanger<String> exchanger;
    public Girl(Exchanger exchanger) {
        this.exchager = exchanger;
    }
    @Override
    public void run() {
        System.out.println("girl准备好的数据");
        // 收到boy的数据(没收到会在这里等待)
        String boyData = exchanger.exchange();
    }
}
全部评论

相关推荐

头像
10-22 20:13
中南大学 Java
序言大家好呀。我是希晨er,一个初入职场的程序猿小登最近上班摸鱼刷到了一篇文章:10年深漂,放弃高薪,回长沙一年有感,还有聊聊30岁大龄程序员过往的心路历程,突然就有点感慨。我如今也做出了和大明哥一样的抉择,只是更早。此外我22年的人生,好像从来没好好记录过。正好现在工作不太忙,就想把这些经历写下来,也希望能得到社区里各位前辈的指点个人背景我是03年出生的西安娃,父母都是普通打工人。刚从中南大学软件工程专业毕业半年,现在在老家的央企过着躺平摆烂的日子成长轨迹从农村到城市的童年我家并不是西安的,只是爸妈在西安上班,从小学之后就把我接到了西安。后来老家房子拆了,爷爷奶奶也搬了过来。农村的生活,我觉...
Yki_:看哭了,恋爱那一段你女朋友说你不够关心她,可你毕竟也愿意遇到矛盾写几千字来和她慢慢分析;说不愿意给她花钱,我感觉可能只是消费观不一样;如果她想留在长沙,也应该提前跟你说开。不过她也许会心疼你放弃大厂offer转向数字马力?我也因为同样的原因有过一段幸福而充满遗憾的感情,不过跟爱情相比确实前途更重要一点。至于offer的选择,换我我也会这么选。把这些旧事记录下来以后,接下来就好好向前看吧,加油兄弟
🍊晨光随笔
点赞 评论 收藏
分享
点赞 评论 收藏
分享
10-14 21:00
门头沟学院 Java
吃花椒的狸猫:这个人说的倒是实话,特别是小公司,一个实习生哪里来的那么多要求
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务