1. Thread creation
1.1 inherit Thread
public class ThreadDemo01 extends Thread { private String name;//Properties of this thread //Pass parameters through full parameter structure public ThreadDemo01(String name) { this.name=name; } //Override run method @Override public void run() { for(int i =1;i<=10;i++) { System.out.println(this.name+"-"+i); try { sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { Thread t1 = new ThreadDemo01("A"); Thread t2 = new ThreadDemo01("B"); Thread t3 = new ThreadDemo01("C"); t1.start();//Start thread t2.start(); t3.start(); } }
1.2 implementation of runnable interface
The Runnalbe interface has only the Run () method, and the Run method must be rewritten to implement this interface.
public class ThreadDemo02 implements Runnable{ private String name; //Construction method public ThreadDemo02(String name) { this.name = name; } //run method @Override public void run() { for(int i=1;i<=10;i++) { System.out.println(this.name+"-"+i); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { //Conventional writing // Thread t1 =new Thread(new ThreadDemo02("A")); // Thread t2 =new Thread(new ThreadDemo02("B")); // Thread t3 =new Thread(new ThreadDemo02("C")); // // t1.start(); // t2.start(); // t3.start(); //Anonymous inner class writing new Thread(new Runnable() {// Runnable() interface @Override public void run() { for (int i = 1; i <= 10; i++) { System.out.println(Thread.currentThread().getName() + "-" + i); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } }); // new Thread(()->{ // for(int i=1;i<=10;i++) { // System.out.println(Thread.currentThread().getName()+"-"+i); // try { // Thread.sleep(200); // } catch (InterruptedException e) { // e.printStackTrace(); // } // } // }).start(); } }
The implementation of Runnable interface is our most commonly used method. Because the opportunity of inheritance is precious, we try our best to use the interface.
There are three ways to create threads through the implementation of Runnable interface: 1. Conventional writing. 2. Anonymous inner class. 3. Lambda expression (because Runnable interface is a functional interface)
1.3 implementation of Callable interface
The Callable interface also inherits the Runnable interface, but the biggest difference between the two is that Callable can have a return value.....
Creating a thread is a callable Run method..
FutureTask class creates thread...
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class ThreadDemo03 implements Callable<Integer>{//This interface can have a return value @Override public Integer call() throws Exception { int s =0; for(int i=1;i<=1000;i++) { s+=i; } return s; } public static void main(String[] args) { FutureTask<Integer> ft =new FutureTask<Integer>(new ThreadDemo03()); ft.run(); try { System.out.println("The result is:"+ft.get()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2. Thread ready
Thread t =new Thread(); t.start();//Start (ready) thread
3. Thread running
4. Thread blocking
4.1 sleep()
sleep() is static method sleep() is static static method, it can not change the object's machine lock, when a synchronized block is called sleep() method, although the thread has entered dormancy, but the object's machine lock has not been released, other threads still can not access the object.
In general, the sleep() method does not release the lock.
4.2 join()
The main thread creates and starts a child thread. If a large number of time-consuming operations are to be performed in the child thread, the main thread will often end before the end of the child thread. If the main thread wants to wait for the execution of the child thread to complete before ending, for example, if the child thread processes a data, the main thread needs to use the join() method to obtain the value in the data.
//Test blocking method: join() public class ThreadBlockDemo01 extends Thread{ @Override public void run() { for(int i=1;i<10;i++) { System.out.println(getName()+":"+i); try { sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { Thread t1 =new ThreadBlockDemo01(); Thread t2 =new ThreadBlockDemo01(); Thread t3 =new ThreadBlockDemo01(); t1.start(); t1.join(); t2.start(); t3.start(); } }
4.3 yield()
yield() returns the currently running thread to the runnable state to allow other threads with the same priority to get the chance to run. Therefore, the purpose of using yield() is to enable proper rotation between threads with the same priority.
In most cases, yield() will cause the thread to go from running state to runnable state, but it may have no effect.
//Test blocking method: yield(): temporarily give up cpu time slice public class ThreadBlockDemo02 extends Thread{ @Override public void run() { for(int i=1;i<=10;i++) { if(i%2==0) {//If i is even, temporarily give up the cpu time slice Thread.yield(); } System.out.println(getName()+":"+i); try { sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { Thread t1 = new ThreadBlockDemo02(); Thread t2 = new ThreadBlockDemo02(); Thread t3 = new ThreadBlockDemo02(); t1.start(); t2.start(); t3.start(); } }
4.4 wait()
The wait() method releases the lock, which is generally used with synchronized() and notifyAll().....