Java knowledge [concurrency tool class]

3. Concurrency tool class

3.1 Concurrency tool class - Hashtable

​The reason for the appearance of Hashtable HashMap is a commonly used collection object in the collection class, but HashMap is thread-unsafe (there may be problems in a multi-threaded environment). In order to ensure the security of data, we can use Hashtable, but Hashtable is inefficient.

Code :

package com.itheima.mymap;

import java.util.HashMap;
import java.util.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 < 51; i++) {
    
    
                hm.put(i + "", i + "");
            }
        });

        t1.start();
        t2.start();

        System.out.println("----------------------------");
        //为了t1和t2能把数据全部添加完毕
        Thread.sleep(1000);

        //0-0 1-1 ..... 50- 50

        for (int i = 0; i < 51; i++) {
    
    
            System.out.println(hm.get(i + ""));
        }//0 1 2 3 .... 50


    }
}

3.2 Concurrent tool class - basic use of ConcurrentHashMap

​The reason for the emergence of ConcurrentHashMap HashMap is a commonly used collection object in the collection class, but HashMap is thread-unsafe (there may be problems in a multi-threaded environment). In order to ensure the security of data, we can use Hashtable, but Hashtable is inefficient.

Based on the above two reasons, we can use ConcurrentHashMap provided by JDK1.5 and later.

Architecture :
insert image description here

Summarize :

​ 1, HashMap is thread-unsafe. There will be data security issues in a multi-threaded environment

​ 2, Hashtable is thread-safe, but it will lock the entire table, which is inefficient

​ 3. ConcurrentHashMap is also thread-safe and efficient. In JDK7 and JDK8, the underlying principles are different.

Code :

package com.itheima.mymap;

import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;

public class MyConcurrentHashMapDemo {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        ConcurrentHashMap<String, String> hm = new ConcurrentHashMap<>(100);

        Thread t1 = new Thread(() -> {
    
    
            for (int i = 0; i < 25; i++) {
    
    
                hm.put(i + "", i + "");
            }
        });


        Thread t2 = new Thread(() -> {
    
    
            for (int i = 25; i < 51; i++) {
    
    
                hm.put(i + "", i + "");
            }
        });

        t1.start();
        t2.start();

        System.out.println("----------------------------");
        //为了t1和t2能把数据全部添加完毕
        Thread.sleep(1000);

        //0-0 1-1 ..... 50- 50

        for (int i = 0; i < 51; i++) {
    
    
            System.out.println(hm.get(i + ""));
        }//0 1 2 3 .... 50
    }
}

3.3 Concurrent tool class - Principle of ConcurrentHashMap 1.7

insert image description here

3.4 Concurrent tool class - Principle of ConcurrentHashMap 1.8

insert image description here
Summarize :

1. If a ConcurrentHashMap object is created with a null parameter construct, nothing will be done. Create a hash table the first time an element is added

​ 2. Calculate the index into which the current element should be stored.

​ 3. If the index position is null, use the cas algorithm to add this node to the array.

4. If the index position is not null, use the volatile keyword to obtain the latest node address at the current position, hang it under it, and become a linked list.

​ 5. When the length of the linked list is greater than or equal to 8, it is automatically converted into a red-black tree 6. The linked list or the head node of the red-black tree is used as the lock object, and the pessimistic lock is used to ensure the security of data during multi-threaded operation of the set

3.5 Concurrency tool class - CountDownLatch

CountDownLatch class:

method explain
public CountDownLatch(int count) The parameter passed the number of threads, indicating the number of waiting threads
public void await() make the thread wait
public void countDown() The current thread has finished executing

Usage scenario: Let a thread wait for other threads to finish executing before executing

Code :

package com.itheima.mycountdownlatch;

import java.util.concurrent.CountDownLatch;

public class ChileThread1 extends Thread {
    
    

    private CountDownLatch countDownLatch;
    public ChileThread1(CountDownLatch countDownLatch) {
    
    
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
    
    
        //1.吃饺子
        for (int i = 1; i <= 10; i++) {
    
    
            System.out.println(getName() + "在吃第" + i + "个饺子");
        }
        //2.吃完说一声
        //每一次countDown方法的时候,就让计数器-1
        countDownLatch.countDown();
    }
}

package com.itheima.mycountdownlatch;

import java.util.concurrent.CountDownLatch;

public class ChileThread2 extends Thread {
    
    

    private CountDownLatch countDownLatch;
    public ChileThread2(CountDownLatch countDownLatch) {
    
    
        this.countDownLatch = countDownLatch;
    }
    @Override
    public void run() {
    
    
        //1.吃饺子
        for (int i = 1; i <= 15; i++) {
    
    
            System.out.println(getName() + "在吃第" + i + "个饺子");
        }
        //2.吃完说一声
        //每一次countDown方法的时候,就让计数器-1
        countDownLatch.countDown();
    }
}

package com.itheima.mycountdownlatch;

import java.util.concurrent.CountDownLatch;

public class ChileThread3 extends Thread {
    
    

    private CountDownLatch countDownLatch;
    public ChileThread3(CountDownLatch countDownLatch) {
    
    
        this.countDownLatch = countDownLatch;
    }
    @Override
    public void run() {
    
    
        //1.吃饺子
        for (int i = 1; i <= 20; i++) {
    
    
            System.out.println(getName() + "在吃第" + i + "个饺子");
        }
        //2.吃完说一声
        //每一次countDown方法的时候,就让计数器-1
        countDownLatch.countDown();
    }
}

package com.itheima.mycountdownlatch;

import java.util.concurrent.CountDownLatch;

public class MotherThread extends Thread {
    
    
    private CountDownLatch countDownLatch;
    public MotherThread(CountDownLatch countDownLatch) {
    
    
        this.countDownLatch = countDownLatch;
    }

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

package com.itheima.mycountdownlatch;

import java.util.concurrent.CountDownLatch;

public class MyCountDownLatchDemo {
    
    
    public static void main(String[] args) {
    
    
        //1.创建CountDownLatch的对象,需要传递给四个线程。
        //在底层就定义了一个计数器,此时计数器的值就是3
        CountDownLatch countDownLatch = new CountDownLatch(3);
        //2.创建四个线程对象并开启他们。
        MotherThread motherThread = new MotherThread(countDownLatch);
        motherThread.start();

        ChileThread1 t1 = new ChileThread1(countDownLatch);
        t1.setName("小明");

        ChileThread2 t2 = new ChileThread2(countDownLatch);
        t2.setName("小红");

        ChileThread3 t3 = new ChileThread3(countDownLatch);
        t3.setName("小刚");

        t1.start();
        t2.start();
        t3.start();
    }
}

Summarize :

​ 1. CountDownLatch(int count): The parameter writes the number of waiting threads. and defines a counter.

​ 2. await(): let the thread wait, when the counter is 0, it will wake up the waiting thread

​ 3. countDown(): Called when the thread is finished executing, the counter will be -1.

3.6 Concurrency tool class - Semaphore

scenes to be used :

​ You can control the number of threads that access a specific resource.

Implementation steps:

1. Someone needs to manage this channel

​ 2. When a car comes in, issue a pass

​ 3. When the car goes out, take back the pass

​ 4. If the permit is issued, other vehicles can only wait

Code :

package com.itheima.mysemaphore;

import java.util.concurrent.Semaphore;

public class MyRunnable implements Runnable {
    
    
    //1.获得管理员对象,
    private Semaphore semaphore = new Semaphore(2);
    @Override
    public void run() {
    
    
        //2.获得通行证
        try {
    
    
            semaphore.acquire();
            //3.开始行驶
            System.out.println("获得了通行证开始行驶");
            Thread.sleep(2000);
            System.out.println("归还通行证");
            //4.归还通行证
            semaphore.release();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }
}

package com.itheima.mysemaphore;

public class MySemaphoreDemo {
    
    
    public static void main(String[] args) {
    
    
        MyRunnable mr = new MyRunnable();

        for (int i = 0; i < 100; i++) {
    
    
            new Thread(mr).start();
        }
    }
}

Guess you like

Origin blog.csdn.net/m0_64550837/article/details/127327652