Day 10 of learning to use IntelliJ IDEA: Java advanced syntax - multithreading

1, Understanding of programs, processes and threads

1. Program

Concept: it is a set of instructions written in a certain language to complete a specific task. Refers to a piece of static code.

2. Process

Concept: an execution process of a program, or a running program.
Note: as the unit of resource allocation, the system will allocate different memory areas for each process at run time

3. Thread

Concept: a process can be further refined into a thread, which is an execution path within a program.
Description: as a unit of scheduling and execution, each thread has an independent running stack and program counter(pc),The overhead of thread switching is small.

Supplement: memory structure

Processes can be subdivided into multiple threads.
Each thread has its own independent: stack, program counter
 Multiple threads share the structure in the same process: method area and heap.

2, Parallelism and concurrency

1. Understanding of single core CPU and multi-core CPU

Single core CPU is actually a fake multithreading, because it can only execute one thread in a time unit. For example: Although there are multiple lanes, there is only one staff member in the toll station charging. Only after charging can it pass through, so the CPU is like a toll collector. If someone doesn't want to pay, the toll collector can "hang" him (hang him until he has figured it out and has the money ready.) But because the CPU time unit is very short, I can't feel it.
If it is multi-core, it can give better play to the efficiency of multithreading. (today's servers are multi-core)
A Java application Exe, in fact, there are at least three threads: main() main thread, gc() garbage collection thread and exception handling thread. Of course, if an exception occurs, it will affect the main thread.

2. Understanding of parallelism and concurrency

Parallel: multiple CPU Perform multiple tasks at the same time. For example: many people do different things at the same time.
Concurrency: one CPU(Using time slice)Perform multiple tasks at the same time. For example: second kill, multiple people do the same thing

3, Two ways to create multithreading

Method 1: inherit Thread class:

1. Create one that inherits from Thread Subclass of class
2. rewrite Thread Class run() --> Declare the operation performed by this thread in run()in
3. establish Thread Object of subclass of class
4. Called through this object start(): ①Start the current thread ② Calling the current thread run()

Explain two questions:
	Question 1: when we start a thread, we must call start(),Cannot call run()Start the thread.
	Problem 2: if you start another thread, you must recreate one Thread Subclass object that calls the start().
/**
 * The creation of multithreading, method 1: inherit from the Thread class
 * 1. Create a subclass that inherits from the Thread class
 * 2. The run() of this class will be overridden by the run() of this class
 * 3. An object that creates a subclass of the Thread class
 * 4. start() is called through this object
 *
 * Example: traverse all even numbers within 100
 *
 */

//1. Create a subclass inherited from Thread class
class MyThread extends Thread {
    //2. Override run() of Thread class
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        //3. Create objects of subclasses of Thread class
        MyThread t1 = new MyThread();

        //4. Call start() through this object: ① start the current thread ② call run() of the current thread
        t1.start();
        //Problem 1: we can't start a thread by calling run() directly.
//        t1.run();

        //Problem 2: start another thread and traverse the even number within 100. You can't let the thread that has started () execute. IllegalThreadStateException will be reported
//        t1.start();
        //We need to recreate a thread object
        MyThread t2 = new MyThread();
        t2.start();

        //The following operations are still performed in the main thread.
        for (int i = 0; i < 100; i++) {
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i + "***********main()************");
            }
        }
    }
}
/**
 * Exercise: create two sub threads, one of which traverses an even number within 100 and the other traverses an odd number within 100
 */
public class ThreadDemo {
    public static void main(String[] args) {
//        MyThread1 m1 = new MyThread1();
//        MyThread2 m2 = new MyThread2();
//
//        m1.start();
//        m2.start();

        //How to create an anonymous subclass of Thread class
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    if(i % 2 == 0){
                        System.out.println(Thread.currentThread().getName() + ":" + i);

                    }
                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    if(i % 2 != 0){
                        System.out.println(Thread.currentThread().getName() + ":" + i);
                    }
                }
            }
        }.start();
    }
}

class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }

    }
}

class MyThread2 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}

Mode 2: implementation of Runnable interface:

1. Create an implementation Runnable Class of interface
2. Implementation class to implement Runnable Abstract methods in: run()
3. Create an object that implements the class
4. Pass this object as a parameter to Thread Class, create Thread Object of class
5. adopt Thread Class start()
package atguigu.java;

/**
 * The second way to create multithreading is to implement the Runnable interface
 * 1. Create a class that implements the Runnable interface
 * 2. The implementation class implements the abstract method in Runnable: run()
 * 3. Create an object that implements the class
 * 4. Pass this object as a parameter to the constructor of Thread class to create the object of Thread class
 * 5. start() is called through the object of Thread class
 *
 */
//1. Create a class that implements the Runnable interface
class MThread implements Runnable{

    //2. Implement the class to implement the abstract method in Runnable: run()
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}

public class ThreadTest1 {
    public static void main(String[] args) {
        //3. Create an object that implements the class
        MThread mThread = new MThread();
        //4. Pass this object as a parameter to the constructor of Thread class and create the object of Thread class
        Thread t1 = new Thread(mThread);
        t1.setName("Thread 1");
        //5. Call start() through the object of Thread class: ① start the Thread ② call the run() of the current Thread -- > call the run() of the target of Runnable type
        t1.start();

        //Start another thread and traverse the even number within 100
        Thread t2 = new Thread(mThread);
        t2.setName("Thread 2");
        t2.start();
    }
}
/**
 * Example: create three windows to sell tickets, and the total number of tickets is 100 Use the way to implement the Runnable interface
 * There is a thread safety problem to be solved.
 */
class Window1 implements Runnable{

    private int ticket = 100;

    @Override
    public void run() {
        while(true){
            if(ticket > 0){
                System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);
                ticket--;
            }else{
                break;
            }
        }
    }
}

public class WindowTest1 {
    public static void main(String[] args) {
        Window1 w = new Window1();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

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

Comparison of the two methods

Under development: implementation is preferred Runnable Interface mode
 Reason: 1. The implementation method does not have the limitation of single inheritance of classes
	 2. The implementation method is more suitable to deal with the situation that multiple threads share data.
Contact: public class Thread implements Runnable
 Same point: both methods need to be rewritten run(),Declare the logic to be executed by the thread in run()Yes.
	  At present, both methods are called to start the thread Thread Class start(). 

4, Common methods in Thread class

  1. start(): start the current thread; Call the run() of the current thread
  2. run(): you usually need to override this method in the Thread class and declare the operation to be performed by the created Thread in this method
  3. currentThread(): a static method that returns the thread executing the current code
  4. getName(): get the name of the current thread
  5. setName(): sets the name of the current thread
  6. yield(): release the execution authority of the current cpu
  7. join(): join() in thread a calling thread b. At this point, thread a enters the blocking state, and thread a ends the blocking state until the thread b is fully executed.
  8. stop(): obsolete. When this method is executed, the current thread is forced to end.
  9. sleep(long millitime): make the current thread "sleep" for the specified millitime milliseconds. The thread is currently blocked for the specified time in milliseconds.
  10. isAlive(): judge whether the current thread is alive
Thread priority:
1.	MAX_PRIORITY: 10
2.	MIN _PRIORITY: 1
3.	NORM_PRIORITY: 5  -->Default Priority 

How to get and set the priority of the current thread:
	getPriority():Gets the priority of the thread
	setPriority(int p):Set thread priority

Note: the high priority thread should seize the execution right of the low priority thread cpu. But only in terms of probability, high priority threads are executed with high probability. This does not mean that only after the high priority thread is executed, the low priority thread will execute.

class HelloThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i % 2 == 0){

//                try {
//                    sleep(10);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
            }

//            if(i % 20 == 0){
//                yield();
//            }
        }
    }

    public HelloThread(String name){
        super(name);
    }
}

public class ThreadMethodTest {
    public static void main(String[] args) {

        HelloThread h1 = new HelloThread("Thread: 1");

//        h1.setName("thread one");
        //Set the priority of threads
        h1.setPriority(Thread.MAX_PRIORITY);

        h1.start();

        //Name the main thread
        Thread.currentThread().setName("Main thread");
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

        for (int i = 0; i < 100; i++) {
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
            }

//            if(i == 20){
//                try {
//                    h1.join();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }

        }

//        System.out.println(h1.isAlive());
    }
}
/**
 * Example: create three windows to sell tickets, and the total number of tickets is 100 Use the method of inheriting Thread class
 *
 * There is a thread safety problem to be solved.
 */
class Window extends Thread{


    private static int ticket = 100;
    @Override
    public void run() {

        while(true){

            if(ticket > 0){
                System.out.println(getName() + ": Ticket No.:" + ticket);
                ticket--;
            }else{
                break;
            }
        }
    }
}


public class WindowTest {
    public static void main(String[] args) {
        Window t1 = new Window();
        Window t2 = new Window();
        Window t3 = new Window();

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

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

supplement

Thread guard is a kind of user thread.

5, Thread lifecycle

Illustration:

explain:
	1. Life cycle focuses on two concepts: state and corresponding method
	2. Attention: Status a-->state b:Which methods are executed (callback methods)
       Active invocation of a method: Status a-->state b
	3. Blocking: a temporary state, which cannot be used as the final state
	   Death: the final state.

6, Thread synchronization mechanism

1. Background

Example: create three windows to sell tickets, and the total number of tickets is 100 Use the way to implement the Runnable interface

  1. Problem: in the process of selling tickets, there are duplicate tickets and wrong tickets -- > there are thread safety problems
  2. The reason for the problem: when a thread operates the ticket and the operation has not been completed, other threads participate and operate the ticket.
  3. How to solve it: when a thread a is operating a ticket, other threads cannot participate. No other thread can start to operate the ticket until thread a has finished operating the ticket. This situation cannot be changed even if thread a is blocked.
  4. Java solution: synchronization mechanism. In Java, we solve the thread safety problem through synchronization mechanism.

Method 1: synchronize code blocks

	synchronized(Synchronization monitor){
      //Code to be synchronized
  	}

explain:

  1. The code that operates the shared data is the code that needs to be synchronized. -- > It cannot contain more code or less code.
  2. Shared data: variables operated by multiple threads. For example, a ticket is sharing data.
  3. Synchronous monitor, commonly known as lock. The object of any class can act as a lock.
    Requirement: multiple threads must share the same lock.

Add: in the way of implementing Runnable interface to create multithreading, we can consider using this as the synchronization monitor.

In the way of inheriting the Thread class to create multithreads, use this as the synchronization monitor with caution, and consider using the current class as the synchronization monitor.

class Window1 implements Runnable{

    private int ticket = 100;
//    Object obj = new Object();
//    Dog dog = new Dog();
    @Override
    public void run() {
//        Object obj = new Object();
        while(true){
            synchronized (this){//this: the only object of Window1 / / method 2: synchronized (dog){

                if (ticket > 0) {

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

                    System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);
                    ticket--;
                } else {
                    break;
                }
            }
        }
    }
}

public class WindowTest1 {
    public static void main(String[] args) {
        Window1 w = new Window1();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

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

class Dog{
}
/**
 * Use synchronous code blocks to solve the Thread safety problem of inheriting Thread class
 *
 * Example: create three windows to sell tickets, and the total number of tickets is 100 Use the method of inheriting Thread class
 *
 * Note: in the way of inheriting Thread class to create multithreads, use this carefully as the synchronization monitor, and consider using the current class as the synchronization monitor.
 */
class Window2 extends Thread{

    private static int ticket = 100;

    private static Object obj = new Object();

    @Override
    public void run() {

        while(true){
            //correct
//            synchronized (obj){
            synchronized (Window2.class){//Class clazz = Window2.class,Window2.class will be loaded only once
                //Wrong way: this represents T1, T2 and T3 objects
//              synchronized (this){

                if(ticket > 0){

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

                    System.out.println(getName() + ": Ticket No.:" + ticket);
                    ticket--;
                }else{
                    break;
                }
            }
        }
    }
}

public class WindowTest2 {
    public static void main(String[] args) {
        Window2 t1 = new Window2();
        Window2 t2 = new Window2();
        Window2 t3 = new Window2();

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

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

Mode 2: synchronization method

If the code that operates on shared data is completely declared in a method, we might as well synchronize this method declaration.

Summary of synchronization methods:
1. The synchronization method still involves the synchronization monitor, but we don't need to declare it explicitly.
2. Non static synchronization method. The synchronization monitor is: this
   The current method of the monitor class is static synchronization
/**
 * Using synchronization method to solve the thread safety problem of implementing Runnable interface
 */
class Window3 implements Runnable {

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            show();
        }
    }

    private synchronized void show(){//Synchronization monitor: this
        //synchronized (this){

            if (ticket > 0) {

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

                System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);
                ticket--;
            }
        //}
    }
}

public class WindowTest3 {
    public static void main(String[] args) {
        Window3 w = new Window3();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

        t1.start();
        t2.start();
        t3.start();
    }
}
/**
 * Using synchronous methods to deal with Thread safety problems in the way of inheriting Thread class
 */
class Window4 extends Thread {

    private static int ticket = 100;

    @Override
    public void run() {

        while (true) {
            show();
        }
    }
    private static synchronized void show(){//Sync monitor: window4 class
        //private synchronized void show() {/ / synchronization monitor: t1,t2,t3. This solution is wrong
        if (ticket > 0) {

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

            System.out.println(Thread.currentThread().getName() + ": Ticket No.:" + ticket);
            ticket--;
        }
    }
}

public class WindowTest4 {
    public static void main(String[] args) {
        Window4 t1 = new Window4();
        Window4 t2 = new Window4();
        Window4 t3 = new Window4();

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");
        
        t1.start();
        t2.start();
        t3.start();
    }
}

Mode 3: Lock lock

/**
 * Three ways to solve thread safety problems: Lock lock --- jdk5 0 NEW
 */
class Window implements Runnable{

    private int ticket = 100;
    //1. Instantiate ReentrantLock
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while(true){
            try{

                //2. Call the locking method lock()
                lock.lock();

                if(ticket > 0){

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

                    System.out.println(Thread.currentThread().getName() + ": Ticket No.:" + ticket);
                    ticket--;
                }else{
                    break;
                }
            }finally {
                //3. Call the unlock method: unlock()
                lock.unlock();
            }
        }
    }
}

public class LockTest {
    public static void main(String[] args) {
        Window w = new Window();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("Window 1");
        t2.setName("Window 2");
        t3.setName("Window 3");

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

Interview question: what are the similarities and differences between synchronized and Lock?

Same: both can solve thread safety problems
 Different: synchronized The mechanism automatically releases the synchronization monitor after executing the corresponding synchronization code
	 Lock Need to start synchronization manually( lock(),At the same time, the end of synchronization also needs to be realized manually( unlock())

Priority of use

Lock - > synchronize code block (has entered the method body and allocated corresponding resources) - > synchronize method (outside the method body)

advantages and disadvantages

The way of synchronization solves the problem of thread safety.---benefit
 When operating synchronization code, only one thread can participate and other threads wait. It is equivalent to a single threaded process with low efficiency.---limitations

Interview questions

Java How to solve the thread safety problem? How many ways? And compare the differences of several ways
synchronized and Lock Comparison of ways to solve thread safety problems

2. Thread safe singleton mode (lazy)

/**
 * Use the synchronization mechanism to rewrite the lazy style in singleton mode to thread safe
 */
public class BankTest {

}

class Bank{

    private Bank(){}

    private static Bank instance = null;

    public static Bank getInstance(){
        //Mode 1: slightly less efficient
//        synchronized (Bank.class) {
//            if(instance == null){
//
//                instance = new Bank();
//            }
//            return instance;
//        }
        //Mode 2: higher efficiency
        if(instance == null){

            synchronized (Bank.class) {
                if(instance == null){

                    instance = new Bank();
                }
            }
        }
        return instance;
    }
}
Interview question: write a thread safe singleton mode.
Hungry man style.
Lazy: provided above.

3. Deadlock problem

1. Understanding of deadlock

Different threads occupy the synchronization resources needed by the other party and do not give up. They are waiting for the other party to give up the synchronization resources they need, forming a thread deadlock

2. Description:

1) After a deadlock occurs, there will be no exception or prompt, but all threads are blocked and cannot continue
2) When we use synchronization, we should avoid deadlock.

3. Examples:

package com.atguigu.java1;

/**
 * Demonstrate thread deadlock
 */
public class ThreadTest {

    public static void main(String[] args) {

        StringBuffer s1 = new StringBuffer();
        StringBuffer s2 = new StringBuffer();

        new Thread(){
            @Override
            public void run() {

                synchronized (s1){

                    s1.append("a");
                    s2.append("1");

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

                    synchronized (s2){
                        s1.append("b");
                        s2.append("2");

                        System.out.println(s1);
                        System.out.println(s2);
                    }
                }
            }
        }.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (s2){

                    s1.append("c");
                    s2.append("3");

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

                    synchronized (s1){
                        s1.append("d");
                        s2.append("4");

                        System.out.println(s1);
                        System.out.println(s2);
                    }
                }
            }
        }).start();
    }
}

4. Code questions

/**
 * The bank has an account.
 There are two depositors who deposit 3000 yuan into the same account, 1000 yuan each time, three times. Print the account balance after each deposit.

    analysis:
 1.Is it a multithreading problem? Yes, two depositor threads
 2.Is there shared data? Yes, account (or account balance)
 3.Are there thread safety issues? have
 4.How to solve thread safety problems? Synchronization mechanism: there are three ways.
 */
class Account{
    private double balance;

    public Account(double balance) {
        this.balance = balance;
    }

    //save money
    public synchronized void deposit(double amt){
        if(amt > 0){
            balance += amt;

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

            System.out.println(Thread.currentThread().getName() + ":Save money successfully. The balance is:" + balance);
        }
    }
}

class Customer extends  Thread{

    private Account acct;

    public Customer(Account acct) {
        this.acct = acct;
    }

    @Override
    public void run() {

        for (int i = 0; i < 3; i++) {
            acct.deposit(1000);
        }
    }
}


public class AccountTest {

    public static void main(String[] args) {
        Account acct = new Account(0);
        Customer c1 = new Customer(acct);
        Customer c2 = new Customer(acct);

        c1.setName("nail");
        c2.setName("B");

        c1.start();
        c2.start();
    }
}

7, Thread communication

1. Three methods involved in thread communication

wait(): once this method is executed, the current thread enters the blocking state and releases the synchronization monitor.
notify(): once this method is executed, a thread waiting will be awakened. If multiple threads are waiting, wake up the one with higher priority.
notifyAll(): once this method is executed, all threads wait ing will be awakened.

Thread communication: wait() / notify() / notifyAll(): these three methods are defined in the Object class.

2. Description

(1) The three methods wait(), notify(), notifyAll() must be used in the synchronization code block or synchronization method.
(2) The caller of the three methods wait(), notify(), notifyAll() must be the synchronization code block or the synchronization monitor in the synchronization method. Otherwise, an IllegalMonitorStateException will appear
(3) The three methods wait(), notify(), notifyAll() are defined in Java Lang. object class.

3. Interview question: what are the similarities and differences between sleep() and wait()?

1. The same point: once the method is executed, the current thread can enter the blocking state.
2. difference:
		1)The two method declarations are in different locations: Thread Class sleep() , Object Class wait()
		2)Different requirements for calling: sleep()It can be called in any required scenario. 
						wait()Must be used in a synchronization code block or synchronization method
	    3)About whether to release the synchronization monitor: if both methods are used in the synchronization code block or synchronization method
	    					   sleep()Does not release the lock, wait()Will release the lock.

4. Examples

/**
 * Example of thread communication: use two threads to print 1-100. Thread 1 and thread 2 print alternately
 */
class Number implements Runnable{
    private int number = 1;
    private Object obj = new Object();
    @Override
    public void run() {

        while(true){

            synchronized (obj) {

                obj.notify();

                if(number <= 100){

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

                    System.out.println(Thread.currentThread().getName() + ":" + number);
                    number++;

                    try {
                        //Make the thread calling the following wait() method enter the blocking state
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }else{
                    break;
                }
            }
        }
    }
}

public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("Thread 1");
        t2.setName("Thread 2");

        t1.start();
        t2.start();
    }
}
/**
 * Application of thread communication: classic example: Producer / consumer problem
 *
 * The producer gives the product to the clerk, and the customer takes the product from the clerk,
 * The shop assistant can only hold a fixed number of products (e.g. 20) at a time. If the producer tries to produce more products, the shop assistant will
 * Will ask the producer to stop and inform the producer to continue production if there is a vacant place in the store; If there is no product in the store
 * If there is a product in the store, the clerk will tell the consumer to wait and inform the consumer to take the product.
 *
 * analysis:
 * 1. Is it a multithreading problem? Yes, producer thread, consumer thread
 * 2. Is there shared data? Yes, clerk (or product)
 * 3. How to solve the thread safety problem? Synchronization mechanism, there are three methods
 * 4. Is thread communication involved? yes
 */
class Clerk{

    private int productCount = 0;
    //yield a product
    public synchronized void produceProduct() {

        if(productCount < 20){
            productCount++;
            System.out.println(Thread.currentThread().getName() + ":Start production" + productCount + "Products");

            notify();

        }else{
            //wait for
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
    //Consumer products
    public synchronized void consumeProduct() {
        if(productCount > 0){
            System.out.println(Thread.currentThread().getName() + ":Start consumption" + productCount + "Products");
            productCount--;

            notify();
        }else{
            //wait for
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Producer extends Thread{//producer

    private Clerk clerk;

    public Producer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(getName() + ":Start production.....");

        while(true){

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produceProduct();
        }
    }
}

class Consumer extends Thread{//consumer
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(getName() + ":Start consuming products.....");

        while(true){

            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.consumeProduct();
        }
    }
}

public class ProductTest {

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

        Producer p1 = new Producer(clerk);
        p1.setName("Producer 1");

        Consumer c1 = new Consumer(clerk);
        c1.setName("Consumer 1");
        Consumer c2 = new Consumer(clerk);
        c2.setName("Consumer 2");

        p1.start();
        c1.start();
        c2.start();
    }
}

5. Lock operation

Summary operation of releasing lock:

Summary of operations that do not release locks:

8, Jdk5 0 how to create a new thread

New method 1: implement Callable interface JDK 5.0 NEW

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
 * The third way to create a thread is to implement the Callable interface--- JDK 5.0 NEW
 */
//1. Create an implementation class that implements Callable
class NumThread implements Callable{
    //2. Implement the call method and declare the operation to be performed by this thread in call()
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if(i % 2 == 0){
                System.out.println(i);
                sum += i;
            }
        }
        return sum;
    }
}

public class ThreadNew {
    public static void main(String[] args) {
        //3. Create an object of the Callable interface implementation class
        NumThread numThread = new NumThread();
        //4. Pass the object of this Callable interface implementation class to the FutureTask constructor as a and create the object of FutureTask
        FutureTask futureTask = new FutureTask(numThread);
        //5. Pass the FutureTask object as a parameter to the constructor of the Thread class, create the Thread object, and call start()
        new Thread(futureTask).start();

        try {
            //6. Get the return value of call method in Callable
            //The return value of get() is the return value of call() overridden by the FutureTask constructor parameter Callable implementation class.
            Object sum = futureTask.get();
            System.out.println("The sum is:" + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}

explain

How to understand implementation Callable Interface is the way to create multithreading than implementation Runnable How powerful is the multithreading method of interface creation?
	1. call()Can return a value.
	2. call()Exceptions can be thrown and captured by external operations to obtain exception information
	3. Callable It supports generics

New thread pool usage: 2

package com.atguigu.java2;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Four ways to create threads: using thread pool
 */

class NumberThread implements Runnable{

    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}

class NumberThread1 implements Runnable{

    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}

public class ThreadPool {

    public static void main(String[] args) {
        //1. Provide a thread pool with a specified number of threads
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
        //Set properties of thread pool
//        System.out.println(service.getClass());
//        service1.setCorePoolSize(15);
//        service1.setKeepAliveTime();

        //2. Execute the operation of the specified thread. You need to provide an object that implements the Runnable interface or the Callable interface implementation class
        service.execute(new NumberThread());//Suitable for Runnable
        service.execute(new NumberThread1());//Suitable for Runnable

//        service.submit(Callable callable);// Suitable for callable
        //3. Close the connection pool
        service.shutdown();
    
}

explain

Benefits:
	1. Improved response speed (reduced time to create new threads)
	2. Reduce resource consumption (reuse threads in the thread pool and do not need to be created every time)
	3. Easy thread management
				 corePoolSize: Size of core pool
				 maximumPoolSize: Maximum number of threads
				 keepAliveTime: How long does the thread last when there is no task

Interview questions

Java How many ways to create multithreading in? Four.

Keywords: Java IntelliJ IDEA intellij-idea

Added by bloodl on Fri, 04 Mar 2022 12:03:33 +0200