1. Java thread creation mode

In Java, there are three ways to create threads:

  1. Inherit the Thread class and override the run() method
  2. Implement the Runnable interface and implement the run() method
  3. Implement the Callable interface and implement the Call () method

Let’s focus on the first two methods.

1. Create threads by inheriting the Thread class

Inheriting Thread classes must override the run() method to define the Thread body in the run() method, which is the entry point for the new Thread. The thread can only be started by calling the start() method; calling the run() method does not start the thread.

Example 1:

Public class ThreadDemo01 extends Thread{public void run() {for(int I =1; i<=20; I++){system.out.println ("... ); }} public static void main(String[] args) {ThreadDemo01 th=new ThreadDemo01(); // Start thread th.start(); //th.run(); For (int I =1; i<=20; I++){system.out.println ("... ); }}}Copy the code

After executing th.start(), this thread is started, and the statements in this thread are the ones written in the run() method.

Starting a new thread is like having two cars running in two lanes without affecting each other.

If this code is not written in a thread, the code in the run() method is placed next to the for loop in the main method, as if two people were walking down a narrow lane with only one person following the other.

By writing this way we can eat and speak again

2. Create threads by implementing the Runnable interface

By implementing the Runnable interface to create threads, the limitations of single inheritance can be avoided and resources can be shared.

Example 2:

@override public void run() {for(int I =1; @override public void run() {for(int I =1; i<=100; I++){system.out.println (" while running... ); } } public static void main(String[] args) { ThreadDemo02 th=new ThreadDemo02(); Thread t=new Thread(th); T.start (); t.start(); for(int i=1; i<=100; I++){system.out.println ("... ); }}}Copy the code

Since there is no way to start a Thread in the Runnable interface, you need to use the Thread class as a proxy class that calls the start() method to start the Thread.

3. Buy train tickets through multi-thread simulation

Example 3:

Public class implements Runnable{// ticket implements Runnable =20; @override public void run() {// loop while(true){if(kets<=0){break; } try { Thread.sleep(200); // Thread sleep 100ms} catch (InterruptedException e) {e.printstackTrace (); } system.out.println (thread.currentThread ().getname ()+" buy "+tikets--+" buy "); } } public static void main(String[] args) { BuyTikets bt=new BuyTikets(); New Thread(bt," zhang SAN ").start(); New Thread(bt," lI si ").start(); New Thread(bt," w5 ").start(); }}Copy the code

The running result of the program is:

Jack is buying the 20th ticket, Jack is buying the 19th ticket, Jack is buying the 18th ticket, Jack is buying the 16th ticket, Jack is buying the 15th ticket, Jack is buying the 13th ticket, Jack is buying the 12th ticket Tom is buying the 11th ticket Tom is buying the 10th ticket Tom is buying the 9th ticket Tom is buying the 8th ticket Tom is buying the 7th ticket Tom is buying the 6th ticket Tom is buying the 5th ticket Li Si is buying the fourth ticket wang Wu is buying the third ticket Zhang SAN is buying the second ticket Li Si is buying the first ticket Wang Wu is buying the 0 ticket Wang Wu is buying the -1 ticketCopy the code

You can see three people buying 20 tickets. One thread represents one person. Twenty tickets are shared by the three people. But there was something wrong with the program, and someone could buy the 0 ticket, the -1 ticket. Two other people bought the same ticket.

2. Thread status

Threading is a process that executes dynamically, and it also has a process from birth to death.

  1. New state: new
  2. Ready state: runnable
  3. Running status: Running
  4. The state is blocked
  5. Execution completed: Dead

The transformation diagram of each state is as follows:

Way to get ready:

  1. Start () method
  2. Block lifting
  3. A thread switches, and the switched thread enters the ready state
  4. Yield ()—- Comity process

How to enter the blocking state:

  1. Sleep () method
  2. The join () method
  3. Wait () method

Way to enter termination state:

  1. Normal execution completed
  2. Destroy () | stop () has been out of date
  3. Manually check by identifier

1. Sleep ()– The thread sleeps

Function:

  1. Analog network delay
  2. Magnify the possibility of problems

However, a thread that goes to sleep using sleep() does not release its own object resources, only CPU resources

Simulate the countdown with the sleep() method

Example 4:

public class Countdown implements Runnable{ public static void main(String[] args) { new Thread(new Countdown()).start(); } @Override public void run() { for(int i=10; i>=0; i--){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if(I ==0){system.out.println ("..."); ); break; } System.out.println(i); }}}Copy the code

The running result of the program is:

10 9 8 7 6 4 3 2 1 Happy New Year...Copy the code

2. Yield ()– Yield to thread

When a thread calls the yield() method, it suspends the currently executing thread object and executes the other threads.

Example 5:

public class YieldDemo implements Runnable{ public static void main(String[] args) { new Thread(new YieldDemo(),"A").start(); new Thread(new YieldDemo(),"B").start(); } @Override public void run() { System.out.println(Thread.currentThread().getName()+"start..." ); Thread.yield(); System.out.println(thread.currentThread ().getName()+"end..." ); }}Copy the code

The running result of the program is:

    A:start...
    B:start...
    A:end...
    B:end...
Copy the code

3. Join ()– join thread, queue cutting thread

Example 6:

public class JoinDemo { public static void main(String[] args) { new Thread(new Father()).start(); }} class implements Runnable{@override public void run() {system.out.println (" implements Runnable ") {@override public void run() {system.out.println (" implements Runnable "); ); System.out.println(" Give the son money, let the son buy vinegar.." ); Thread th=new Thread(new Son()); th.start(); try { th.join(); // Thread merge} catch (InterruptedException e) {e.printStackTrace(); System.out.println(" son lost, hurry to find son.." ); } system.out.println (" dumplings in vinegar ~"); }} class Son implements Runnable{@override public void run() {system.out.println (" implements Runnable ") {@override public void run() {system.out. ); System.out.println(" there is a game arcade on the roadside, go to play 10 seconds..." ); for(int i=1; i<=10; i++){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(i+"s..." ); } system.out.println (" go and buy vinegar...") ); System.out.println(" Pass daddy the vinegar..." ); }}Copy the code

The running result of the program is:

Eating dumplings without vinegar... Give the son money to buy vinegar.. Took the money, went to buy vinegar... There is a roadside video game city, go to play 10s... 1s... 2s... 3s... 4s... 5s... 6s... 7s... 8s... 9s... 10s... Go get some vinegar... Pass the vinegar to Daddy... Dumplings dipped in vinegar ~Copy the code

3. Thread safety

We see that some people buy the first ticket, some two people buy the same ticket. In this case, thread-safety issues can only occur when multiple threads are operating on the same resource.

To address this security issue, we can control thread safety by synchronizing the synchronized keyword

The keyword synchronized can synchronize methods and blocks.

Synchronous methods can synchronize static methods as well as member methods

Methods for synchronizing blocks:

Synchronized (class | this | resources)} {codeCopy the code

Class the class object of a class a class has only one class object

The synchronization scope is too large and inefficient.

The synchronization range is too small to be locked.

Synchronized is used as a keyword to lock things should be invariable, changed things can not be locked.

Rewrite simulation buying tickets:

Example 7:

public class BuyTikets implements Runnable { @Override public void run() { while (true) { synchronized (Tikets.class) { if (Tikets.tikets <= 0) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } system.out.println (thread.currentThread ().getname () + "" + Tikets -- +" "); } } } public static void main(String[] args) { BuyTikets td = new BuyTikets(); New Thread(td, "zhang SAN ").start(); New Thread(td, "三 ").start(); New Thread(td, "w ").start(); } } class Tikets { static int tikets = 20; }Copy the code

The running result of the program is:

John is buying the 20th ticket John is buying the 19th ticket John is buying the 18th ticket John is buying the 17th ticket John is buying the 15th ticket John is buying the 14th ticket John is buying the 12th ticket John is buying the 11th ticket Wang Wu is buying the tenth ticket, Li Si is buying the ninth ticket, Li Si is buying the seventh ticket, Li Si is buying the fifth ticket, li Si is buying the third ticket, Li Si is buying the first ticketCopy the code

This way, there will be no more mistakes in buying tickets.