Location>code7788 >text

java basics - threading (basic) notes

Popularity:931 ℃/2024-09-09 18:48:51

Because of the need for enemy tanks to be able to move freely and fire bullets, and for our tanks to be able to move and fire bullets, these are going to use the knowledge of threading.

 

 

According to JConsole monitoring thread execution, it is found that, the main thread has finished executing and the sub-threads have not finished executing, it does not mean that the current process is dead, only when all the sub-threads have finished executing, the main process will end.

 

The real effect of multithreading is start0(), not run.
package ;

//Demonstrates creating a thread by inheriting the Thread class
public class Thread01 {
    public static void main(String[] args) throws InterruptedException {

        Runtime runtime = ();
        //Get the number of cpu's/cores of the current computer
        int cpuNums = ();
        ("Current number of cpu's = " + cpuNums);

        //Creates a Cat object that can be used as a thread.
        Cat cat = new Cat();
        /* *
        (1)
            public synchronized void start() {
                start0();
            }
        (2) start0() is a local method, it is called by JVM, the underlying is c/c++ implementation.
           The real effect of multi-threading is start0(), not run.

        private native void start0().
*/

        ();//Start the thread -> eventually the cat run method will be executed.
//();//The run method is just a normal method, it doesn't really start a thread, it just finishes the run method before moving on to the next one

//Explanation: When the main thread starts a sub-thread Thread-0, the main thread will not block and will continue to execute.
//At this point, the main thread and the child threads are executing alternately...
        ("Main thread continues execution" + ().getName());//Name main
        for(int i = 0; i < 60; i++) {
            ("Main thread i=" + i);
            //Putting the main thread to sleep
            (1000);
        }
    }
}

//1. When a class inherits the Thread class, it can be used as a thread.
//2. We'll rewrite the run method with our own business code.
//3. run method, the Thread class implements the run method of the Runnable interface.
class Cat extends Thread {

    int times = 0;
    @Override
    public void run() {//Rewrite the run method with your own business logic.

//This thread is every 1 second. Output "Meow, I'm a kitten" on the console.
        while (true) {
            ("Meow, I'm a kitty" + (++times) + " thread name = " + ().getName());
            try {
                //Hibernate the thread for 1 second ctrl+alt+t
                (1000);
            } catch (InterruptedException e) {
                ();
            }
            if(times == 80) {
                break;//When times reaches 80, exit while, at which point the thread exits...
            }
        }
    }
}

 

 

584, Runnable Creation Threads and Static Proxy Patterns

The code also emulates the static proxy model

package ;

//Developing threads by implementing the interface Runnable
public class Thread02 {
    public static void main(String[] args) {

//        Dog dog = new Dog();
//        //(); you can't call start here, Runnable doesn't have a start method.
//
//        //Create a Thread object, put the dog object (which implements Runnable), into the Thread.
//        Thread thread = new Thread(dog);
//        ();

        Tiger tiger = new Tiger();
        ThreadProxy threadProxy = new ThreadProxy(tiger);//Polymorphism of interfaces: a reference to an interface can point to a class that implements the interface
        ();
    }
}

class Animal {}
class Tiger extends Animal implements Runnable {

    @Override
    public void run() {
        ("The tiger wailed...");
    }
}

//ThreadProxy class , simulates a minimalist Thread class, that is, you can treat the ThreadProxy class as a Thread class.
class ThreadProxy implements Runnable {

    private Runnable target = null;//property of type Runnable

    @Override
    public void run() {
        if(target != null) {
            ();//Dynamic binding (run type Tiger)
        }
    }

    public ThreadProxy(Runnable target) {//The formal parameter is an object of class Tiger
        this.target = target;
    }

    public void start() {
        start0();//This method is the real multithreading method
    }

    public void start0() {
        run();
    }

}

class Dog implements Runnable { //Developing threads by implementing the Runnable interface

    int count = 0;
    @Override
    public void run() {
        while (true) {
            ("Puppy woof woof . . hi " + (++count) + ().getName());
            try {
                (1000);
            } catch (InterruptedException e) {
                ();
            }
            if(count == 10) {
                break;
            }
        }
    }
}

 

585, Multiple Subthread Cases

package ;

//The main thread starts two child threads
public class Thread03 {
    public static void main(String[] args) {
        T1 t1 = new T1();
        T2 t2 = new T2();

        Thread thread1 = new Thread(t1);
        Thread thread2 = new Thread(t2);

        ();//Start the first thread
        ();//Start the 2nd thread
    }
}

class T1 implements Runnable {

    int count = 0;
    @Override
    public void run() {
        while(true) {
            //Output "hello,world" every 1 second, 10 times.
            ("hello,world " + (++count));
            try {
                (1000);
            } catch (InterruptedException e) {
                ();
            }
            if(count == 10) {
                break;
            }
        }
    }
}

class T2 implements Runnable {

    int count = 0;
    @Override
    public void run() {
        while (true) {
            //Output "hi" every 1 second, 5 times.
            ("hi " + (++count));
            try {
                (1000);
            } catch (InterruptedException e) {
                ();
            }
            if(count == 5) {
                break;
            }
        }
    }
}

 

 

586, Multi-threaded ticketing issue

 

There will be negative tickets appearing because 3 processes are grabbing a ticket at the same time and the ticket has been sold for 0, but you can't stop the sale.

package ;

//Using multi-threading, simulate three windows selling 100 tickets at the same time.
public class sellTicket {
    public static void main(String[] args) {

        //beta (software)
//        SellTicket01 sellTicket01 = new SellTicket01();
//        SellTicket01 sellTicket02 = new SellTicket01();
//        SellTicket01 sellTicket03 = new SellTicket01();
//
//        //Overselling occurs here, that is, selling too much, with negative votes appearing
//        ();//Start the ticketing thread
//        ();//Starting the Ticketing Thread
//        ();//Starting the Ticketing Thread

        ("===Tickets sold using implementation interface approach =====");
        SellTicket02 sellTicket02 = new SellTicket02();
        new Thread(sellTicket02).start();//Thread 1 - Window
        new Thread(sellTicket02).start();//Thread 1 - Window
        new Thread(sellTicket02).start();//Thread 1 - Window
    }
}

//Using the Thread Method
class SellTicket01 extends Thread {

    private static int ticketNum = 100;//Let multiple threads share ticketNum
    @Override
    public void run() {
        while (true) {
            if(ticketNum <= 0) {
                ("Ticket sales are over...");
                break;
            }

            //Sleep 50 ms, analog
            try {
                (50);
            } catch (InterruptedException e) {
                ();
            }
            ("Window " + ().getName() + " Sold a ticket"
                    + " Remaining tickets = " + (--)ticketNum));
        }
    }
}

//implementation interface
class SellTicket02 implements Runnable {

    private int ticketNum = 100;//Let multiple threads share ticketNum
    @Override
    public void run() {
        while (true) {
            if(ticketNum <= 0) {
                ("Ticket sales are over...");
                break;
            }

            //Sleep 50 ms, analog
            try {
                (50);
            } catch (InterruptedException e) {
                ();
            }
            ("Window " + ().getName() + " Sold a ticket"
                    + " Remaining tickets = " + (--)ticketNum));
        }
    }
}

 

587, notification of thread exit

 

 

package ;

public class ThreadExit {
    public static void main(String[] args) throws InterruptedException {
        T t = new T();
        ();

        //If you want the main thread to control the termination of the t1 thread, you must be able to modify the loop
//Terminate the t1 thread by having t1 exit the run method -> this is called the notification method

//Let the main thread sleep for 2 seconds, then notify t1 to exit.
        ("main thread hibernating for 2s..."));
        (2 * 1000);
        (false);
    }
}

//Output a sentence every 50 milliseconds
class T extends Thread {

    private int count = 0;
    //Set a control variable to exit the loop if loop is false.
    private boolean loop = true;

    @Override
    public void run() {
        while (loop) {
            try {
                (50);//Let the current thread sleep for 50ms
            } catch (InterruptedException e) {
                ();
            }
            ("T Running..." + (++count));
        }
    }
    public void setLoop(boolean loop) {
        this.loop = loop;
    }
}

 

588, thread break

 

package ;

public class ThreadMethod01 {
    public static void main(String[] args) throws InterruptedException {
        A a = new A();
        ("Old Han.");
        (Thread.MIN_PRIORITY);//1
        ();//Start a sub-thread

//The main thread prints hi 5 times, and then I interrupt the sleep of the subthread.
        for(int i = 0; i < 5; i++) {
            (1000);
            ("hi " + i);
        }

        (() + " Priority of thread = " + ());
        ();//When execution reaches this point, it interrupts the t-thread's hibernation
    }
}

class A extends Thread {//Customized Thread Classes
    @Override
    public void run() {
        while (true) {
            for (int i = 0; i < 10; i++) {
                //().getName() gets the name of the current thread
                (().getName() + " Eat the bun~~~" + i);
            }
            try {
                (().getName() + " Dormant~~~");
                (20000);//Hibernate for 20 seconds
            } catch (InterruptedException e) {
                //When the thread executes an interrupt method, it catches an exception and can add its own business code.
//InterruptedException is an interrupted exception caught.
                (().getName() + " was interrupted");
            }
        }
    }
}

 

589, Threadjacking

package ;

public class ThreadMethod02 {
    public static void main(String[] args) throws InterruptedException {
        B b = new B();
        ();

        for (int i = 1; i <= 20; i++) {
            (1000);
            ("Main thread (minion) ate " + i +" bun");
            if(i == 5) {
                ("The main thread (the little brother) lets the sub-thread (the boss) eat first.");
                //join, thread-joining
//                ();//This is equivalent to letting the t2 thread finish executing first

                ();//Courtesy, not always successful, (Boss) eat too much, have to eat until the oxen, (Little brother) no need to let the

                ("When the thread (the boss) finishes eating, the main thread (the little brother) eats next");
            }
        }
    }
}

class B extends Thread {
    @Override
    public void run() {
        for (int i = 0; i <= 20; i++) {
            try {
                (1000);//Hibernate for 1 second
            } catch (InterruptedException e) {
                ();
            }
            ("Child thread (boss) ate " + i + " bun");
        }
    }
}

 

590, thread plugging exercise

package ;

public class ThreadMethod02 {
    public static void main(String[] args) throws InterruptedException {
        B b = new B();
        Thread thread = new Thread(b);//Creating sub-threads
        for (int i = 1; i <= 10; i++) {
            ("hi " + i);
            (1000);
            if(i == 5) {//It means that the main thread outputs hi 5 times
                ();//Starts a subthread that outputs hello
                ();//Immediately insert the thread subthread, into the main thread, so that the thread executes first
            }
        }
        ("End of main thread...");
    }
}

class B implements Runnable {

    private int count = 0;
    @Override
    public void run() {
        while(true) {
            ("hello " + (++count));
            try {
                (1000);
            } catch (InterruptedException e) {
                ();
            }
            if(count == 10) {
                ("End of sub-thread...");
                break;
            }
        }
    }
}

 

 

591, Guardian Threads

 

Below we test how to set a thread as a daemon thread

package ;

public class ThreadMethod03 {
    public static void main(String[] args) throws InterruptedException {
        MyDaemonThread myDemonThread = new MyDaemonThread();

        //If we want the child thread to end automatically when the main thread ends
//Simply make the child thread a daemon thread
        (true);
        ();

        for (int i = 1; i <= 10; i++) {//main thread, the child thread is an infinite loop, when the main thread is finished, the child thread will not be finished
            ("Baoqiang is hard at work...");
            (1000);
        }
    }
}

class MyDaemonThread extends Thread {
    @Override
    public void run() {
        for (; ; ) {//infinite loop
            try {
                (1000);
            } catch (InterruptedException e) {//Sleep 50 milliseconds
                ();
            }
            ("Happy chatting between Ma Rong and David Song, hahaha~~~");
        }
    }
}

 

 

592, 7 major states of the thread

 

 

Write a program to view thread status

package ;

public class ThreadState {
    public static void main(String[] args) throws InterruptedException {
        //Create a thread and see what its state is right away!
        C c = new C();
        (() + " Status " + ());
        ();

        //After starting, use a loop to keep looking at the current state of the thread as long as it has not terminated
        while ( != ()) {
            (() + " Status " + ());
            (1000);//Putting the main thread to sleep
        }

        //When it exits the while loop, that means it has terminated, and then see what its final state is
        (() + " Status " + ());
    }
}

class C extends Thread {
    @Override
    public void run() {
        while (true) {
            for (int i = 0; i < 10 ; i++) {
                ("hi " + i);
                try {
                    (1000);
                } catch (InterruptedException e) {
                    ();
                }
            }
            break;
        }
    }
}

 

 

593, Thread synchronization mechanism

 

 

You should also add hibernation code to the run method.

The code in this section solves the problem of selling negative tickets.

package ;

//Using multi-threading, simulate three windows selling 100 tickets at the same time.
public class sellTicket {
    public static void main(String[] args) {

        //beta (software)
//        SellTicket01 sellTicket01 = new SellTicket01();
//        SellTicket01 sellTicket02 = new SellTicket01();
//        SellTicket01 sellTicket03 = new SellTicket01();
//
//        //Overselling occurs here, that is, selling too much, with negative votes appearing
//        ();//Starting the Ticketing Thread
//        ();//Starting the Ticketing Thread
//        ();//Start the ticketing thread

//        ("==== Use the implementation interface approach to ticket =====");;
//        SellTicket02 sellTicket02 = new SellTicket02();
//        new Thread(sellTicket02).start();//Thread 1 - Window
//        new Thread(sellTicket02).start();//Thread 1 - Window
//        new Thread(sellTicket02).start();//Thread 1 - Window

//test (machinery etc)
        SellTicket03 sellTicket03 = new SellTicket03();
        new Thread(sellTicket03).start();//Thread 1 - Window
        new Thread(sellTicket03).start();//Thread 1 - Window
        new Thread(sellTicket03).start();//Thread 1 - Window
    }
}

//Implement an interface approach to thread synchronization using synchronized
class SellTicket03 implements Runnable {

    private int ticketNum = 100;//Let multiple threads share ticketNum
    private boolean loop = true;//Controlling run method variables

    public synchronized void sell() {//Synchronized methods, at the same moment, there can only be one thread to execute the sell method
        if (ticketNum <= 0) {
            ("Ticket sales are over...");
            loop = false;
            return;
        }

        //Sleep 50 ms, analog
        try {
            (50);
        } catch (InterruptedException e) {
            ();
        }
        ("Window " + ().getName() + " Sold a ticket"
                + " Remaining tickets = " + (--)ticketNum));
    }

    @Override
    public void run() {//synchronized can not modify the run method, because if you do, it is equivalent to enter the 3 people can only be sold to a ticket, the other 2 people into the white, a total of three queues
//Without trimming, it's the equivalent of selling 1 person's ticket, then the next person's, for a total of 1 queue
        while (loop) {
            sell();//The sell method is a synchronized method
//Sleep 50 ms, analog
            try {
                (50);
            } catch (InterruptedException e) {
                ();
            }

        }
    }

    //Using the Thread Method
    class SellTicket01 extends Thread {

        private static int ticketNum = 100;//Let multiple threads share ticketNum

        @Override
        public void run() {
            while (true) {
                if (ticketNum <= 0) {
                    ("Ticket sales are over...");
                    break;
                }

                //Sleep 50 ms, analog
                try {
                    (50);
                } catch (InterruptedException e) {
                    ();
                }
                ("Window " + ().getName() + " Sold a ticket"
                        + " Remaining tickets = " + (--)ticketNum));
            }
        }
    }

    //implementation interface
    class SellTicket02 implements Runnable {

        private int ticketNum = 100;//Let multiple threads share ticketNum

        @Override
        public void run() {
            while (true) {
                if (ticketNum <= 0) {
                    ("Ticket sales are over...");
                    break;
                }

                //Sleep 50 ms, analog
                try {
                    (50);
                } catch (InterruptedException e) {
                    ();
                }
                ("Window " + ().getName() + " Sold a ticket"
                        + " Remaining tickets = " + (--)ticketNum));
            }
        }
    }
}

 

 

594, Mutually exclusive locks

 

package ;

//Using multi-threading, simulate three windows selling 100 tickets at the same time.
public class sellTicket {
    public static void main(String[] args) {

        //test (machinery etc)
        SellTicket03 sellTicket03 = new SellTicket03();
        new Thread(sellTicket03).start();//Thread 1 - Window
        new Thread(sellTicket03).start();//Thread 1 - Window
        new Thread(sellTicket03).start();//Thread 1 - Window
    }
}

//Implement an interface approach to thread synchronization using synchronized
class SellTicket03 implements Runnable {

    private int ticketNum = 100;//Let multiple threads share ticketNum
    private boolean loop = true;//Controlling run method variables

    Object object = new Object();

    //Synchronized methods (static) lock on the current class itself.
//Lao Han's interpretation.
//1. public synchronized static void m1() {} The lock is added to the
    //2. If you implement a synchronization block in a static method.
    /*
    synchronized () {
    ("m2");
    }
    */
    public synchronized static void m1() {}

    public static void m2() {
        synchronized (SellTicket03.class) {
            ("m2");
        }
    }

    //1. public synchronized void sell() {} is a synchronized method
//2. the lock is on this object
//3. you can also write synchronize on the code block, synchronize the code block, the mutual exclusion lock is still on this object
    public /*synchronized*/ void sell() {//Synchronized methods, at the same moment, there can only be one thread to execute the sell method
        synchronized (/*this*/ object) {
            if (ticketNum <= 0) {
                ("Ticket sales are over...");
                loop = false;
                return;
            }

            //Sleep 50 ms, analog
            try {
                (50);
            } catch (InterruptedException e) {
                ();
            }
            ("Window " + ().getName() + " Sold a ticket"
                    + " Remaining tickets = " + (--)ticketNum));
        }
    }

    @Override
    public void run () {//synchronized can not modify the run method, because if you do, it is equivalent to enter the 3 people can only be sold to a ticket, the other 2 people into the white, a total of three queues
//Without trimming, it's the equivalent of selling 1 person's ticket, then the next person's, for a total of 1 queue
        while (loop) {
            sell();//The sell method is a synchronized method
//Sleep 50 ms, analog
            try {
                (50);
            } catch (InterruptedException e) {
                ();
            }

        }
    }
}

//Using the Thread Method
// new SellTicket01().start()
// new SellTicket01().start() ,new out a different object, can't use mutual exclusion locks
class SellTicket01 extends Thread {

    private static int ticketNum = 100;//Let multiple threads share ticketNum

//    public void m1() {
//        synchronized (this) {
//            ("hello");
//        }
//    }
    
    @Override
    public void run() {
        while (true) {
            if(ticketNum <= 0) {
                ("Ticket sales are over...");
                break;
            }

            //Sleep 50 ms, analog
            try {
                (50);
            } catch (InterruptedException e) {
                ();
            }
            ("Window " + ().getName() + " Sold a ticket"
                    + " Remaining tickets = " + (--)ticketNum));
        }
    }
}

 

595, Thread deadlocks and lock releases

A deadlocked run results in a stuck result, so it's important to write code that avoids the

package ;

//Simulating thread deadlocks
public class DeadLock {
    public static void main(String[] args) {

        //Simulating Deadlock Phenomena
        DeadLockDemo A = new DeadLockDemo(true);
        ("Thread A");
        DeadLockDemo B = new DeadLockDemo(false);
        ("Thread B.");

        ();
        ();

    }
}

//threading
class DeadLockDemo extends Thread {
    static Object o1 = new Object();// Guarantees multi-threading, sharing a single object, here static is used.
    static Object o2 = new Object();
    boolean flag;

    public DeadLockDemo(boolean flag) {//constructor
        this.flag = flag;
    }

    //Analysis of the following business logic
//1. if flag is T, thread A first gets/holds the lock on o1, then tries to get the lock on o2.
//2. if thread A can't get a lock on an o2 object, it will be Blocked
//3. if flag is F, thread B first gets/holds the lock on o2, then tries to acquire the lock on o1.
//4. if thread B fails to get a lock on the o1 object, it will be Blocked
    public void run() {
        if(flag) {
            synchronized (o1) {//Object Mutual Exclusion Lock, the following is the synchronization code, someone else must get the lock in order to execute the following code
                (().getName() + "Enter 1");
                synchronized (o2) { // Here you get the right to monitor the li object
                    (().getName() + "enter 2");
                }
            }
        } else {
            synchronized (o2) {
                (().getName() + "Enter 3");
                synchronized (o1) {// Here you get the right to monitor the li object
                    (().getName() + "enter 4");
                }
            }
        }
    }
}

 

 

 

597, Threaded Homework 1

 

The thought process is shown below:

The notification can be done by setting a boolean variable in thread A. In thread B, since there is now an A object, the variable is set to false by the A object, and thread A exits.

 

package ;

import ;
import ;
import ;

public class Homework01 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B(a);//Be sure to note that you put the A object into B first to control a after startup

        ();
        ();
    }
}

//Creating the A-Thread class
class A extends Thread {
    private boolean loop = true;

    public void setLoop(boolean loop) { //You can modify the loop variable
        this.loop = loop;
    }

    @Override
    public void run() {
        //Output 1-100 digital
        while (loop) {
            ((int)(() * 100 + 1));
            //hibernation
            try {
                (1000);
            } catch (InterruptedException e) {
                ();
            }
        }
    }
}

class B extends Thread {
    private A a;
    private Scanner scanner = new Scanner();//Use this object to get user input

    public B(A a) {//In the constructor, pass in the class A object directly
        this.a = a;
    }

    @Override
    public void run() {
        while (true) {
            //Receive user input
            ("Please enter your command (Q) for Exit:").//Type q and enter
            char key = ().toUpperCase().charAt(0);
            if (key == 'Q') {
                //Terminate thread A with a notification
                (false);
                ("Thread B exits.");
                break;
            }
        }
    }
}

 

598, Threaded Homework 2

 

The idea is shown below: it's a bit like the ticketing problem

 

package ;

import ;
import ;
import ;
import ;

public class Homework01 {
    public static void main(String[] args) {
        T t = new T();
        Thread thread1 = new Thread(t);
        ("t1");
        Thread thread2 = new Thread(t);
        ("t2");

        ();
        ();
    }
}

//Programming threads for withdrawals
//1, because here involves multiple threads sharing a resource, just need to put multiple threads into the resource can be, so we use the implementation of Runnable method
//2, take out 1000 at a time
class T implements Runnable {
    private int money = 10000;

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

            //1, here the use of synchronized thread synchronization
//2,When multiple threads reach this point, they compete for the lock on this object.
//3, which thread contends for (acquires) this object lock, the synchronized code block will be executed, after the execution, it will release this object lock.
//4,If you can't contend for this object lock, it is blocked and ready to be contended.
//5,This object lock is a non-fair lock.
            synchronized (this) {
                //Determine if the balance is sufficient
                if (money < 1000) {
                    ("Insufficient balance");
                    break;
                }

                money -= 1000;
                (().getName() + " 1000 taken out, current balance = " + money);
            }

            //Hibernate 1s
            try {
                (1000);
            } catch (InterruptedException e) {
                ();
            }
        }
    }
}