并发包

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();
    }
}