Multithreaded basic learning

Multithreading

Thread introduction

  • Program: an ordered collection of instructions and data, which is only a static concept.

  • Process is an execution process of executing program. As a dynamic concept, it is the unit of system resource allocation.

  • A process can contain multiple threads and have at least one thread

  • Real multithreading means that there are multiple CPUs, i.e. multiple cores, such as servers. If the simulated multithreading is essentially in the same cpu, it can only execute one code task in the same time unit, not at the same time. It is just the illusion of fast switching.

  • Threads are independent execution paths.

  • Multithreading is developed in the process, and the thread operation is scheduled by the scheduler without human intervention.

  • Concurrency control needs to be added to solve the problem of resource grabbing.

Inherit Thread class

package Thread.lesson1;

//Method 1 for creating a Thread: inherit the Thread class, rewrite the run method, and call start to start the Thread

//Note: thread startup is not necessarily executed immediately and is scheduled by cpu
public class Dom1 extends Thread{
    @Override
    public void run(){
        //run method thread body
        for (int i = 0 ; i < 20 ; i ++) {
            System.out.println("Threadstudy"+i);
        }
    }

    public static void main(String[] args) {
        //Main thread main thread
        //Create a thread object
        Dom1 dom1 = new Dom1();
        //Calling the run method will only be executed in sequence, while the start method can be scheduled by the cpu to interact with multiple threads at the same time
        //dom1.run();
        //Call the start method to start the thread,
        dom1.start();
        //Write a test to see the effect
        for (int i = 0 ; i < 1000 ; i ++){
            System.out.println("Thread------" + i);
        }
    }
}

Network diagram Download

import java.net.URL;

public class dom1 extends Thread {
    private String url;
    private String name;

    //constructor 
    public dom1(String url,String name){
        this.url = url;
        this.name = name;
    }

    //The execution body of the download image thread
    @Override
    public void run() {
        webDown webdown = new webDown();
        try {
            webdown.down(url,name);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Downloaded file named" + name);
    }

    public static void main(String[] args) {

        //My head
        dom1 t1 = new dom1("http://i2.hdslb.com/bfs/face/536ff5e823cb3c354a71880edb3a15c826d5634d.jpg",
                          "536ff5e823cb3c354a71880edb3a15c826d5634d.jpg");
        //Mad god head
        dom1 t2 = new dom1("http://i2.hdslb.com/bfs/face/83bb511365da513c55aa3d1958524f3b7db40684.jpg",
                "83bb511365da513c55aa3d1958524f3b7db40684.jpg");
        //Head of director
        dom1 t3 = new dom1("http://i1.hdslb.com/bfs/face/f85fbedb0a6bfebedba167791a816e1b36f757d9.jpg",
                "f85fbedb0a6bfebedba167791a816e1b36f757d9.jpg");
        
        //Execution thread
        t1.start();
        t2.start();
        t3.start();
    }
}

//Downloader
class webDown{
    public void down(String url,String name) throws IOException {
        //File tool class: FileUtils
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO Abnormal, down There is something wrong with the method");
        }
    }
}

The download results are not executed from top to bottom. The reason is the same as above.

Implement Runnable interface

  • Compared with the Thread class, Runnable is more recommended and avoids the limitations of single inheritance. However, Runnable is flexible and can enable an object to be used by multiple threads.

Use Runnable to modify the above two examples

//Create thread method 2: implement the runnable interface and rewrite the run method. The execution thread needs to drop into the runnable interface implementation class and call the start method
public class dom2 implements Runnable{
    @Override
    //run method thread body
    public void run() {
        for (int i = 0; i < 20 ; i++){
            System.out.println("Look at the code" +i);
        }
    }

    public static void main(String[] args) {
        //Create an implementation object of the Runnable interface
        dom2 dom2 = new dom2();

        //Create a thread object and start the thread proxy through the thread object
        //Thread thread = new Thread();
        //thread.start();
        // Equivalent to the above two sentences, abbreviated as:
        new Thread(dom2).start();

        for (int i = 0; i < 1000 ; i++){
            System.out.println("study" +i);
        }
    }
}

import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public class dom1 implements Runnable {
    private String url;
    private String name;

    //constructor 
    public dom1(String url,String name){
        this.url = url;
        this.name = name;
    }

    //The execution body of the download image thread
    @Override
    public void run() {
        webDown webdown = new webDown();
        try {
            webdown.down(url,name);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Downloaded file named" + name);
    }

    public static void main(String[] args) {

        //My head
        dom1 t1 = new dom1("http://i2.hdslb.com/bfs/face/536ff5e823cb3c354a71880edb3a15c826d5634d.jpg",
                          "536ff5e823cb3c354a71880edb3a15c826d5634d.jpg");
        //Mad god head
        dom1 t2 = new dom1("http://i2.hdslb.com/bfs/face/83bb511365da513c55aa3d1958524f3b7db40684.jpg",
                "83bb511365da513c55aa3d1958524f3b7db40684.jpg");
        //Head of director
        dom1 t3 = new dom1("http://i1.hdslb.com/bfs/face/f85fbedb0a6bfebedba167791a816e1b36f757d9.jpg",
                "f85fbedb0a6bfebedba167791a816e1b36f757d9.jpg");

        //Execution thread
        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();
    }
}

//Downloader
class webDown{
    public void down(String url,String name) throws IOException {
        //File tool class: FileUtils
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO Abnormal, down There is something wrong with the method");
        }
    }
}

Understanding concurrency problems

//Multiple threads operate on an object at the same time
//Example of buying a train ticket

//Problems are found after execution. When multiple threads execute the same resource, the thread is unsafe and the data is disordered. Concurrency problem
public class dom3 implements Runnable{
    @Override
    public void run() {
        while (true){
            if(Nums <= 0){
                break;
            }
            try {
                //Analog delay, delay 0.2s
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //Thread.currentThread().getName(): current thread name
            System.out.println(Thread.currentThread().getName()+"Got the second" +Nums--+"ticket");
        }
    }

    //Number of votes
    private int Nums = 10;

    public static void main(String[] args) {
        dom3 dom3 = new dom3();

        //You can name each thread
        new Thread(dom3,"Two dogs").start();
        new Thread(dom3,"Lao Liu").start();
        new Thread(dom3,"cattle").start();
    }
}

Tortoise and rabbit race

//Simulated tortoise rabbit race (classic written test questions)
//Define a track distance, getting closer and closer to the finish line
//Judge whether the game is over
//Print out the winner
//The game begins
//The rabbit has to sleep
//Bastard won
public class dom4 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            //Let the rabbit sleep. Sleep for a while every ten steps. Sleep for 0.01s is enough. You can't sleep at the beginning
            if(Thread.currentThread().getName().equals("rabbit")&& i%10==0 &&i!=0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //Judge whether the game is over
            boolean flag = gameOver(i);
            //The game is over
            if(flag){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"-->Run away"+ i + "step");
        }
    }

    //Winner - static
    private static String Winner;

    //Judge whether to complete the game
    private boolean gameOver(int stops) {
        if (Winner != null) {
            //Winner already exists
            return true;
        }
        {
            if (stops >= 100) {
                Winner = Thread.currentThread().getName();
                System.out.println("winner is" + Winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        dom4 dom4 = new dom4();

        new Thread(dom4,"rabbit").start();
        new Thread(dom4,"tortoise").start();
    }
}

Implement Callable interface*

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

//Thread creation method 3: Callable interface
//You can define the return value and throw an exception
public class dom5 implements Callable<Boolean> {
    private String url;
    private String name;

    //constructor 
    public dom5(String url,String name){
        this.url = url;
        this.name = name;
    }

    //The execution body of the download image thread
    @Override
    public Boolean call() {
        webDown webdown = new webDown();
        try {
            webdown.down(url,name);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Downloaded file named" + name);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //My head
        dom5 t1 = new dom5("http://i2.hdslb.com/bfs/face/536ff5e823cb3c354a71880edb3a15c826d5634d.jpg",
                "536ff5e823cb3c354a71880edb3a15c826d5634d.jpg");
        //Mad god head
        dom5 t2 = new dom5("http://i2.hdslb.com/bfs/face/83bb511365da513c55aa3d1958524f3b7db40684.jpg",
                "83bb511365da513c55aa3d1958524f3b7db40684.jpg");
        //Head of director
        dom5 t3 = new dom5("http://i1.hdslb.com/bfs/face/f85fbedb0a6bfebedba167791a816e1b36f757d9.jpg",
                "f85fbedb0a6bfebedba167791a816e1b36f757d9.jpg");

        //Create execution service:
        ExecutorService ser = Executors.newFixedThreadPool(3);
        //Submit for execution
        Future<Boolean> r1 = ser.submit(t1);
        Future<Boolean> r2 = ser.submit(t2);
        Future<Boolean> r3 = ser.submit(t3);

        //Get results
        boolean rs1 = r1.get();
        boolean rs2 = r2.get();
        boolean rs3 = r3.get();
        //Shut down service
        ser.shutdown();
    }
}

//Downloader
class webDown{
    public void down(String url,String name) throws IOException {
        //File tool class: FileUtils
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO Abnormal, down There is something wrong with the method");
        }
    }
}

Static proxy

//Surrogate marriage
//Proxy mode: both real objects and proxy objects should implement the same interface
//The proxy object should represent the real role. The proxy object can do things that the proxy object can't do. The real object focuses on doing its own things
//The bottom implementation idea of thread
public class dom6 {
    public static void main(String[] args) {

        
        //WeddingCompany weddingCompany = new WeddingCompany(new You());
        //weddingCompany.HappyMarry();
        new WeddingCompany(new You()).HappyMarry();//Lite 
    }
}

//interface: interface
interface Marry{
    void HappyMarry();
}

//Real role
class You implements Marry{
    @Override
    public void HappyMarry() {
        System.out.println("I'm married");
    }
}
//delegable role
class WeddingCompany implements Marry{

    //Agent - real target role
    private Marry target;

    public WeddingCompany(Marry target){
        this.target = target;
    }
    @Override
    public void HappyMarry() {
        after();
        this.target.HappyMarry();
        before();
    }
    private void after(){
        System.out.println("Decorate the venue");
    }
    private void before(){
        System.out.println("Closing payment");
    }
}



Lamda expression

Abbreviated code

/*
Derivation of lamda expression
*/

public class dom7 {

    //Static inner class
    static class lamda2 implements Lamda{
        @Override
        public void lamDa() {
            System.out.println("i like lamda2");
        }
    }
    public static void main(String[] args) {
        Lamda la = new Lam();
        la.lamDa();

        la = new lamda2();
        la.lamDa();

        //Local inner class
        class lamda3 implements Lamda{
            @Override
            public void lamDa() {
                System.out.println("i like lamda3");
            }
        }
        la = new lamda3();
        la.lamDa();

        //Anonymous inner class. There is no class name. You must use the interface or parent class
        la = new Lamda() {
            @Override
            public void lamDa() {
                System.out.println("i like lamda4");
            }
        };
        la.lamDa();

        //Simplify with Lamda
        //lamda simplifies step by step, simplifying parameter types, parentheses and curly braces
        //lamda expressions can only be reduced to one line when there is only one line. Multiple lines need to be {} wrapped
        //Must be a functional interface (interface has only one method)
        //The parameter type can also be removed from multiple parameters, and all parameters to be removed;
        la = () ->{
            System.out.println("i like lamda5");
        };
        la.lamDa();

        la = () ->System.out.println("i like lamda6");
        la.lamDa();

    }
}

//Define a functional interface
interface Lamda{
    void lamDa();
}

//Implementation class
class Lam implements Lamda{

    @Override
    public void lamDa() {
        System.out.println("i like lamda");
    }
}

Thread stop

  • Five thread states:
    • Creation status: new, that is, new status
    • Ready state: enter after calling the start () method
      • Blocking state: call sleep or lock state in operation, end of state and readiness again.
    • Running state: actually executing thread body code block
    • Dead state: thread interrupt or end
//It is recommended that the thread stop itself
//Dead circulation or stop is not recommended, that is, the party fee that jdk does not recommend is forcibly stopped
public class dom8 implements Runnable{
    //Set a flag bit
    private boolean flag = true;
    @Override
    public void run() {
        int i = 0;
        while (flag){
            System.out.println("run---Thread"+i);
            i++;
        }
    }

    //Set a public method to stop the thread and change the flag bit
    public void stop(){
        this.flag= false;
    }

    public static void main(String[] args) {
        dom8 dom8 = new dom8();

        new Thread(dom8).start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("main"+i);
            if(i == 900){
                //Call the stop method to switch Peugeot and stop the thread
                dom8.stop();
                System.out.println("run The thread should stop");
            }
        }
    }
}

Thread sleep

  • sleep: Unit - milliseconds (1s = 1000ms);
  • An exception needs to be thrown
  • Each object has a lock, and sleep will not release the lock*
//Simulate the network delay, amplify the occurrence of the problem, and return to the above ticket purchase problem
public class dom9 implements Runnable{
    @Override
    public void run() {
        while (true){
            if(Nums <= 0){
                break;
            }
            try {
                //Analog delay, delay 0.2s
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //Thread.currentThread().getName(): current thread name
            System.out.println(Thread.currentThread().getName()+"Got the second" +Nums--+"ticket");
        }
    }

    //Number of votes
    private int Nums = 10;

    public static void main(String[] args) {
        dom3 dom3 = new dom3();

        //You can name each thread
        new Thread(dom3,"Two dogs").start();
        new Thread(dom3,"Lao Liu").start();
        new Thread(dom3,"cattle").start();
    }
}

import java.text.SimpleDateFormat;
import java.util.Date;

//Analog countdown
public class dom9{

    public static void main(String[] args) {
        //count down
//        try {
//            TimeDown();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        //Print current time
        Date date = new Date(System.currentTimeMillis());//Get the current system time
        while (true){
            try {
                Thread.sleep(1000);
                System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));
                date = new Date(System.currentTimeMillis());//Update time
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void TimeDown() throws InterruptedException {
        int time = 10;
        while (true) {
            Thread.sleep(100);
            System.out.println(time--);
            if (time<=0){
                break;
            }
        }
    }
}

Thread yield

//Change the process from running state to ready state without blocking
//Comity does not necessarily succeed. It depends on your mood
public class dom10 {
    public static void main(String[] args) {
        myYield myYield = new myYield();

        new Thread(myYield,"a").start();
        new Thread(myYield,"b").start();
    }
}

class myYield implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"Thread starts execution");
        Thread.yield();//Comity
        System.out.println(Thread.currentThread().getName()+"Thread stop execution");
    }
}

Thread enforcement - join

//The join method can be understood as forcibly jumping in the queue, blocking other processes and being overbearing!
public class dom11 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("vip coming"+i);
        }
    }

    public static void main(String[] args) {
        //Start thread
        dom11 dom11 = new dom11();
        Thread thread = new Thread(dom11);
        thread.start();

        //Main thread
        for (int i = 0; i < 500; i++) {
            if (i == 200){
                try {
                    thread.join();//Jump the queue, let the current thread step aside first, and so on. Let other threads go first
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("main"+i);
        }
    }
}

Observe thread state - state

//Observe the status of the test thread
public class dom12 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            //The thread starts for five seconds
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("`````");
        });

        //Observation state
        Thread.State state = thread.getState();
        System.out.println(state); //NEW

        //Observe after startup
        thread.start();
        state = thread.getState();
        System.out.println(state); //RUNNABLE

        while (state!=Thread.State.TERMINATED){//The thread does not terminate and is always in the output state
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            state = thread.getState();//Update thread status
            System.out.println(state);//Output status
        }
    }
}

Priority of thread - priority

//Test thread priority
//Priority range 1-10; If the range is exceeded, an error will be reported. The higher the priority, the more resources the cpu gives, which is not absolute!
public class dom13 {
    public static void main(String[] args) {
        //Main thread default priority - 5
        System.out.println(Thread.currentThread().getName()+Thread.currentThread().getPriority());

        MyPriority myPriority = new MyPriority();
        Thread t1 = new Thread(myPriority);
        Thread t2 = new Thread(myPriority);
        Thread t3 = new Thread(myPriority);
        Thread t4 = new Thread(myPriority);
        Thread t5 = new Thread(myPriority);
        Thread t6 = new Thread(myPriority);
        Thread t7 = new Thread(myPriority);
        Thread t8 = new Thread(myPriority);

        //Set the priority before starting!
        t1.start();

        t2.setPriority(1);
        t2.start();

        t3.setPriority(6);
        t3.start();

        t4.setPriority(Thread.MAX_PRIORITY);
        t4.start();

        t5.setPriority(Thread.NORM_PRIORITY);
        t5.start();

    }
}

class MyPriority implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"____"+Thread.currentThread().getPriority());
    }
}

daemon thread

//Test: protect you all your life
//Life is only 36500 days

//The program will not wait for the execution of the daemon thread. The program must ensure that the execution of the user thread is completed, that is, the daemon thread is still protected until the end of the process.
public class dom14 {

    public static void main(String[] args) {
        dom dom = new dom();
        You2 you2 = new You2();

        Thread thread = new Thread(dom);
        thread.setDaemon(true);//The default is flash. All normal threads are user threads

        thread.start();//Daemon thread start

        new Thread(you2).start();
    }
}

class dom implements Runnable{

    @Override
    public void run() {
        while (true){
            System.out.println("Guard you");
        }
    }
}

class You2 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("You should live a happy life all your life");
        }
        System.out.println("---goodBye! word---");
    }
}

Thread synchronization mechanism

  • Queues and locks

  • Safety = = reduced performance (you can't have both fish and bear's paw)

Three unsafe cases

//Unsafe ticket buying

//Threads are unsafe and have negative numbers -- each thread has its own independent workspace and does not affect each other in its own memory.
public class dom15{
    public static void main(String[] args) {
        BuyTicket buyTicket1 = new BuyTicket();
        
        new Thread(buyTicket1,"Zhao").start();
        new Thread(buyTicket1,"money").start();
        new Thread(buyTicket1,"Sun").start();
        new Thread(buyTicket1,"Lee").start();
    }
}

//Ticket buying method
class BuyTicket implements Runnable{

    private int Nums = 10;
    private boolean flag = true;
    
    @Override
    public void run() {
        while (flag){
           buy();
        }
    }

    private void buy(){
        if(Nums<=0){
            return;
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"Got it"+Nums--);
    }
}


//Unsafe withdrawal
//Two people withdraw money together
public class dom16 {
    public static void main(String[] args) {

        Account account = new Account(100,"fund");

        back you = new back(account,50,"you");
        back her = new back(account,100,"she");

        you.start();
        her.start();

    }
}

//account
class Account{
    int money;
    String name;

    public Account(int money,String name) {
        this.money = money;
        this.name = name;
    }
}

//Bank: simulated withdrawal
class back extends Thread{
    //account
    Account account ;
    //How much is it now
    int nowMoney;
    //How much is it
    int DrawingMoney;

    public back(Account account,int DrawingMoney,String name) {
        super(name);
        this.account = account;
        this.DrawingMoney = DrawingMoney;
    }

    public void run(){
        //Judge whether the money is enough
        if(account.money-DrawingMoney < 0){
            System.out.println(Thread.currentThread().getName()+"The money is not enough");
            return;
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        account.money = account.money - DrawingMoney ;
        nowMoney = nowMoney + DrawingMoney;

        System.out.println(this.getName()+"--Now there are--"+ nowMoney);
        System.out.println(account.name+"The balance is"+account.money);


    }
}
import java.util.ArrayList;
import java.util.List;

//Thread unsafe collection, it is difficult to achieve the goal of creating all 1000 threads
//Note that the system can create a limited number of threads
public class dom17 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>() ;
        for(int i = 0;i< 1000;i++) {
            new Thread(()->list.add(Thread.currentThread().getName())).start();
        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}


Synchronization method and synchronization block synchronized

Optimize and modify the above three unsafe cases - lock

//Unsafe ticket buying

//Thread unsafe, negative number
public class dom15{
    public static void main(String[] args) {
        BuyTicket buyTicket1 = new BuyTicket();

        new Thread(buyTicket1,"Zhao").start();
        new Thread(buyTicket1,"money").start();
        new Thread(buyTicket1,"Sun").start();
        new Thread(buyTicket1,"Lee").start();
    }

}

//Ticket buying method
class BuyTicket implements Runnable{

    private int Nums = 10;
    private boolean flag = true;

    @Override
    public void run() {
        while (flag){
           buy();
        }
    }

    //The synchronized synchronization method locks this to ensure thread safety
    private synchronized void buy(){
        if(Nums<=0){
            return;
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"Got it"+Nums--);
    }

}


//Unsafe withdrawal
//Two people withdraw money together
public class dom16 {
    public static void main(String[] args) {

        Account account = new Account(100,"fund");

        back you = new back(account,50,"you");
        back her = new back(account,100,"she");

        you.start();
        her.start();

    }
}

//account
class Account{
    int money;
    String name;

    public Account(int money,String name) {
        this.money = money;
        this.name = name;
    }
}

//Bank: simulated withdrawal
class back extends Thread{
    //account
    Account account ;
    //How much is it now
    int nowMoney;
    //How much is it
    int DrawingMoney;

    public back(Account account,int DrawingMoney,String name) {
        super(name);
        this.account = account;
        this.DrawingMoney = DrawingMoney;
    }

    public void run(){
        //Synchronization block
        //The key lies in the object of the lock. The object of the lock must be the amount of change. If the bank cannot be locked, the bank card must be locked
        synchronized (account){
            //Judge whether the money is enough
            if(account.money-DrawingMoney < 0){
                System.out.println(Thread.currentThread().getName()+"The money is not enough");
                return;
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            account.money = account.money - DrawingMoney ;
            nowMoney = nowMoney + DrawingMoney;

            System.out.println(this.getName()+"--Now there are--"+ nowMoney);
            System.out.println(account.name+"The balance is"+account.money);
        }
    }
}
import java.util.ArrayList;
import java.util.List;

//Thread unsafe collection, it is difficult to achieve the goal of creating all 1000 threads
//Note that the system can create a limited number of threads
public class dom17 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>() ;
        for(int i = 0;i< 1000;i++) {
            new Thread(()->{
                synchronized (list){
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}


CopyOnWriteArrayList

  • Collection of security types
import java.util.concurrent.CopyOnWriteArrayList;

//A collection of test juc security types
public class dom18 {
    public static void main(String[] args) {
        //And contract
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
        for (int i = 0; i < 1000; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

deadlock

  • Two threads are waiting for each other to release resources and are deadlocked with each other
  • When a synchronization block has more than two locks, it is prone to the problem of life and death lock
//Deadlock problem
public class dom19 {
    public static void main(String[] args) {
        new Thread(new MakeUp(1,"Cuihua")).start();
        new Thread(new MakeUp(0,"Hemp flowers")).start();
    }
}

//Lipstick
class Lipstick{}

//mirror
class Mirror{}

class MakeUp extends Thread{

    //There is only one resource
    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();

    //selector
    int choise;
    //role
    String name;

    MakeUp(int choise,String name){
        this.choise = choise;
        this.name = name;
    }

    @Override
    public void run() {
        makeup();
    }

    //Make up and hold each other's locks
    private void makeup(){
        if(choise == 0){
            //Lock current resource
            synchronized (lipstick){
                System.out.println(this.name + "Get lipstick");
                try {
                    //Get another resource in a second
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (mirror){
                    System.out.println(this.name+"Get the mirror");
                }
            }
        }else {
            synchronized (mirror){
                System.out.println(this.name + "Get the mirror");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lipstick){
                    System.out.println(this.name+"Get lipstick");
                }
            }
        }
    }
}
  • In the above example, two objects occupy each other's required resources and are waiting to release resources. A deadlock problem occurs. Take out the "lock in lock" to solve the problem.
    //Make up and hold each other's locks
    private void makeup(){
        if(choise == 0){
            //Lock current resource
            synchronized (lipstick){
                System.out.println(this.name + "Get lipstick");
                try {
                    //Get another resource in a second
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (mirror){
                System.out.println(this.name+"Get the mirror");
            }
        }else {
            synchronized (mirror){
                System.out.println(this.name + "Get the mirror");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (lipstick){
                System.out.println(this.name+"Get lipstick");
            }
        }
    }

Lock lock

  • Lock: explicit lock. Manual switch is required

    synchronized: an implicit lock that is automatically released out of the scope

  • lock: only code block locks, no method locks

  • Lock lock has better performance and better expansibility

import java.util.concurrent.locks.ReentrantLock;

//Lock lock
public class dom20 {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();

        new Thread(ticket,"Lao Zhang").start();
        new Thread(ticket,"Two dogs").start();
        new Thread(ticket,"Three guns").start();
    }
}

class Ticket implements Runnable{

    int Num = 10;
    
    //Define lock lock
    private final ReentrantLock lock = new ReentrantLock();
    @Override
    public void run() {
        while (true){
            try {
                lock.lock();//Lock
                    if(Num>0){
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+"--Got the second"+ Num-- +"Ticket");
                    }else {
                        break;
                    }
            }finally {
                lock.unlock();//Release lock
            }
        }
    }
}

Producer consumer issues*

Pipe program method

//Producer consumer model - using buffer to solve: pipe process method

//Producer, consumer, product, buffer
public class dom21 {
    public static void main(String[] args) {
        SyContainer syContainer = new SyContainer();

        new Productor(syContainer).start();
        new Consumer(syContainer).start();
    }
}

//producer
class Productor extends Thread{
    SyContainer container;

    public Productor(SyContainer container){
        this.container = container;
    }

    //production
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Chicken(i));
            System.out.println("Produced" + i +"Chicken");
        }
    }
}

//consumer
class Consumer extends Thread{
    SyContainer container;

    public Consumer(SyContainer container){
        this.container = container;
    }

    //consumption
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Consumption" + container.pop().id + "Chicken");
        }
    }
}

//product
class Chicken {
    //Product number
    int id;
    public Chicken(int id){
        this.id = id;
    }
}

//buffer
class SyContainer{

    //Container size
    Chicken[] chickens = new Chicken[10];

    //Capacity counter
    int str = 0;

    //Producers throw in products
    public synchronized void push(Chicken chicken){
        //Full, production stop
        if(str == chickens.length){
        //Inform consumers to consume and producers to wait
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //Not full, production
        chickens[str] = chicken;
        str++;
        //Inform consumers of consumption
        this.notifyAll();
    }

    //Consumer products
    public synchronized Chicken pop(){
        //Judge whether it can be consumed
        if(str==0){
            //wait
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //Can consume
        str--;
        Chicken chicken = chickens[str];

        //Notify the producer of production after consumption
        this.notifyAll();
        return chicken;
    }
}

Signal lamp method

//Signal lamp method - solve through flag bit - flag
public class dom22 {
    public static void main(String[] args) {
        Tv tv = new Tv();
        new player(tv).start();
        new watcher(tv).start();
    }
}

//producer
class player extends Thread{
    Tv tv;
    public player(Tv tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if(i%2==0){
                this.tv.play("Tom and Jerry");
            }else {
                this.tv.play("Shaking tiktok records good life");
            }
        }
    }
}

//consumer
class watcher extends Thread{
    Tv tv;
    public watcher(Tv tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            tv.watch();
        }
    }
}

//Products - programs
class Tv{
    //Actors perform and the audience wait; The audience watched and the actors waited
    String voice;
    boolean flag = true;

    //perform
    public  synchronized void play(String voice){
        if(!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("Performed:" +voice);
        this.notifyAll();//Notification, wake up
        this.voice = voice;
        this.flag = !this.flag;
    }
    //watch
    public synchronized void watch(){
        if(flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Watched"+ voice);
        //Inform the actors to perform
        this.notifyAll();
        this.flag = !this.flag;
    }
}

Thread pool

  • Refer to the callable interface
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//Side thread pool
public class dom23 {
    public static void main(String[] args) {
        //Create thread pool
        ExecutorService service = Executors.newFixedThreadPool(10);//Thread pool size

        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());

        //Close connection
        service.shutdown();
    }
}

class MyThread implements Runnable{

    @Override
    public void run() {
            System.out.println(Thread.currentThread().getName());
    }
}

Keywords: Java Multithreading

Added by phprocker on Mon, 18 Oct 2021 09:51:32 +0300