Application: A runnable program, such as QQ, WeChat, etc.
An application has at least one process
- Process: An execution unit in an application
Threads: An execution unit in a process (the bottom worker)
Note: Each thread is independent of each other, does its own work, does not affect each other, if there are multiple threads in the same process, then these threads share all the resources in the process
Thread life cycle:
- New
- ready (runnable)
- running
- Blocking (yield,sleep,wait,join, etc.)
- Dead
As shown in the following figure:
How threads work:
After a thread is created and started by the strat() method, it is no longer under our control and will execute its own tasks. When we start a thread, it will not go to work immediately, but will be ready (Runnable). The real running of the thread must be done through the thread scheduling of the cpu (that is, it must wait for the cpu to allocate time slices). Threads may not be able to complete tasks during this period of time. After the time slice is over, threads return to their ready state, wait for the next cpu allocation time slice, and grab the time slice before continuing to work. Once the work is finished, they will enter a dead state and wait for recycling.
Thread creation in java
Method 1: Inherit the Thread class
class MyThread1 extends Thread{ public void run(){ for(int i=0;i<1000;i++){ System.out.println("Who are you?"); } } }
Method 2: Implement Runnable
class MyThread3 implements Runnable{ public void run(){ for(int i=0;i<1000;i++){ System.out.println("I'm delivering"); } } }
Note: After implementing the Runnable interface in the second way, there is no start() method to start a thread, because there is only one run method defined in the interface, which is simply used to define the thread to execute tasks. To start a thread, you have to create a Thread object to pass this task object in.
Method 3: Anonymous internal class creation (which is also our most common method)
Thread t4 = new Thread(){ public void run(){ for(int i=0;i<1000;i++){ System.out.println("I buy water and drink it"); } } };
Some commonly used methods in threads
getName: Get the name of the current thread
Thread.currentThread(): Get the name of the thread executing the current task/method`
getPriority(): Gets the priority of the current thread
setPriority(): Sets the priority of the current thread
Priority level 1-10, default is 5
In theory, threads with higher priority are more likely to grab time slices, but the reality is that threads can grab time slices
-isDaemon(): Judges that a thread is a daemon thread (for example, gc)
-setDaemon(true): Set the current thread as a daemon thread
- Daemon thread: Background thread, when none of the foreground threads in the program is running, the background thread will end automatically
-Thread.sleep(long time): allow a thread to sleep for a period of time
Note: Thread.sleep(1000) threads do not immediately enter the running state, but instead enter the ready state, allocate time slices, and then rerun
Thread.yield(): blocking
Note: This method immediately puts the thread in a ready state
join(): Whoever joins in, blocks whoever joins out, and waits for whoever finishes execution first
* Thread A {
Thread B. join(); // Wait until it finishes executing
}
wait(): Block (wait)
The -wait method is inside the Object
-notify(): Wake up the next queued thread
-notifyAll: Wake up all queued threads at the same time
Story of Jack and Rose and FuckMan for Daemon Threads
public static void main(String[] args) { Thread rose = new Thread(){ public void run(){ for(int i=0;i<10;i++){ System.out.println("rose:Let me go!"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Sound effect:Ah Ah Ah Ah Po Tong~"); } }; Thread jack = new Thread(){ public void run(){ while(true){ System.out.println("jack:You jump!I jump!"); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; Thread fuckMan = new Thread(){ public void run(){ while(true){ System.out.println("fuckMan:Son of bitch!"); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; jack.setDaemon(true);//Set Jack as the daemon thread fuckMan.setDaemon(true);//Also set as daemon thread rose.start(); jack.start(); fuckMan.start(); } }
Usage of blocking thread join: blocking whoever has a join in it or clicking it out waits for whoever executes it first
/** * join:Whoever joins in will block whoever joins out, whoever points out the join will wait for whoever executes it first * */ public class ThreadDemo5 { public static void main(String[] args) { Thread t1 =new Thread(){ public void run(){ System.out.println("Under Movie..."); for(int i=0;i<=100;i++){ System.out.println("Downloaded"+i+"%"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Download complete!"); } }; Thread t2 = new Thread(){ public void run(){ try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Start watching movies..."); System.out.println("Finished reading"); } }; t1.start(); t2.start(); } }
Concurrency issues with threads
Threads may cause concurrency problems when executed asynchronously, at which point you need to consider locks to allow the thread to execute synchronously.
synchronized:Locked
* Whoever accesses this method first, then puts a lock on it and others can only do so
* Wait outside until the previous thread has finished executing before entering the method
public synchronized int getBean(){ if(bean==0){ throw new RuntimeException("There are no beans left"); } bean--; System.out.println(bean); Thread.yield(); return bean; }
There is also a synchronization block, which can be guaranteed to be called by only one thread at a time if the code is wrapped in a synchronization block
synchronized(this){}
synchronized(this){ System.out.println(name+"Trimming clothes..."); Thread.sleep(3000); }