「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」
并发工具类
public class MyHashMapDemo {
public static void main(String[] args) throws InterruptedException {
HashMap<String, String> hm = new HashMap<>();
Thread t1 = new Thread(()->{
for (int i = 0; i < 25; i++) {
hm.put(i+"",i+"");
}
});
Thread t2 = new Thread(()->{
for (int i = 25; i < 50; i++) {
hm.put(i+"",i+"");
}
});
t1.start();
t2.start();
System.out.println("-------------------");
// 为了t1和t2能把数据全部添加完毕
Thread.sleep(1000);
for (int i = 0; i < 51; i++) {
System.out.println(hm.get(i+""));
}
}
}
打印结果会出现 null null 47 48 49
Hashtable HashMap 是线程不安全的(多线程环境下可能会存在问题)。 为了保证数据的安全性,我们可以使用Hashtable,但是Hashtable的效率低下。
public class MyHashTableDemo {
public static void main(String[] args) throws InterruptedException {
Hashtable<String, String> hm = new Hashtable<>();
Thread t1 = new Thread(()->{
for (int i = 0; i < 25; i++) {
hm.put(i+"",i+"");
}
});
Thread t2 = new Thread(()->{
for (int i = 25; i < 50; i++) {
hm.put(i+"",i+"");
}
});
t1.start();
t2.start();
System.out.println("-------------------");
// 为了t1和t2能把数据全部添加完毕
Thread.sleep(1000);
for (int i = 0; i < 51; i++) {
System.out.println(hm.get(i+""));
}
}
}
ConcurrentHashMap:
public class MyConcurrentHashMapDemo {
public static void main(String[] args) throws InterruptedException {
ConcurrentHashMap<String, String> hm = new ConcurrentHashMap<>();
Thread t1 = new Thread(()->{
for (int i = 0; i < 25; i++) {
hm.put(i+"",i+"");
}
});
Thread t2 = new Thread(()->{
for (int i = 25; i < 50; i++) {
hm.put(i+"",i+"");
}
});
t1.start();
t2.start();
System.out.println("-------------------");
// 为了t1和t2能把数据全部添加完毕
Thread.sleep(1000);
for (int i = 0; i < 51; i++) {
System.out.println(hm.get(i+""));
}
}
}
小结:
ConcurrentHashMap1.7版本原理解析:
jdk 1.7时, 在默认情况下,最多允许16个线程同时访问。
CountDownLatch
public class ChildThread extends Thread{
private CountDownLatch countDownLatch;
public ChildThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
// 1. 吃饺子
for (int i = 0; i < 10; i++) {
System.out.println(getName() + "在吃第" + i+ "个饺子");
}
// 2. 吃完说一声
// 每一次countdown方法的时候,就让计数器-1
countDownLatch.countDown();
}
}
public class ChildThread2 extends Thread{
private CountDownLatch countDownLatch;
public ChildThread2(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
// 1. 吃饺子
for (int i = 0; i < 15; i++) {
System.out.println(getName() + "在吃第" + i+ "个饺子");
}
// 2. 吃完说一声
// 每一次countdown方法的时候,就让计数器-1
countDownLatch.countDown();
}
}
public class ChildThread3 extends Thread{
private CountDownLatch countDownLatch;
public ChildThread3(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
// 1. 吃饺子
for (int i = 0; i < 20; i++) {
System.out.println(getName() + "在吃第" + i+ "个饺子");
}
// 2. 吃完说一声
// 每一次countdown方法的时候,就让计数器-1
countDownLatch.countDown();
}
}
public class MontherThread extends Thread{
private CountDownLatch countDownLatch;
public MontherThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
// 1.等待
try {
// 当计数器编程0的时候,会自动唤醒这里等待的线程
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 2. 收拾碗筷
System.out.println("妈妈收拾碗筷");
}
}
public class MyCountDownLatchDemo {
public static void main(String[] args) {
// 1.创建CountDownLatch的对象,需要传递给四个线程
// 在底层就定义了一个计数器,此时计数器的值就是3
CountDownLatch countDownLatch = new CountDownLatch(3);
// 2.创建四个线程对象并开启他们。
MontherThread montherThread = new MontherThread(countDownLatch);
montherThread.start();
ChildThread t1 = new ChildThread(countDownLatch);
t1.setName("小明");
ChildThread2 t2 = new ChildThread2(countDownLatch);
t2.setName("小黑");
ChildThread3 t3 = new ChildThread3(countDownLatch);
t3.setName("小白");
t1.start();
t2.start();
t3.start();
}
}
Semaphore
public class MyRunnable implements Runnable {
// 1. 获取管理员对象
private Semaphore semaphore = new Semaphore(2);
@Override
public void run() {
// 2.获得通行证
try {
semaphore.acquire();
System.out.println("拿到通行证开始行驶");
Thread.sleep(2000);
System.out.println("归还通行证");
// 3. 开始行驶
// 4. 归还通行证
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MySemaphoreDemo {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
for (int i = 0; i < 100; i++) {
new Thread(mr).start();
}
}
}