1. Create a thread
There are two ways to create threads in Java: using the Thread class and using the Runnable interface. When using the Runnable interface, you need to create a Thread instance. Therefore, whether you create a thread through the Thread class or the Runnable interface, you must create an instance of the Thread class or its subclass. Thread constructor:
Method 1: Inherit the Thread class and override the run method
}
}
class Demo extends Thread{
public void run(){
for(int i=0;i<60;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
Just like people are born, old, sick and die, threads also have to go through four different states: starting (waiting), running, hanging and stopping. These four states can be controlled through methods in the Thread class. The methods related to these four states in the Thread class are given below.
The thread does not execute the code in the run method immediately after it is established, but is in a waiting state. When the thread is in the waiting state, you can set various attributes of the thread through the methods of the Thread class, such as the thread's priority (setPriority), thread name (setName), and thread type (setDaemon).
When the start method is called, the thread starts executing the code in the run method. The thread enters the running state. You can use the isAlive method of the Thread class to determine whether the thread is running. When the thread is in the running state, isAlive returns true. When isAlive returns false, the thread may be in the waiting state or in the stopped state. The following code demonstrates the switching between the three states of thread creation, running and stopping, and outputs the corresponding isAlive return value.
Once the thread starts executing the run method, it will not exit until the run method is completed. However, during the execution of the thread, there are two methods that can be used to temporarily stop the thread execution. These two methods are suspend and sleep. After using suspend to suspend a thread, you can wake it up through the resume method. After using sleep to make the thread sleep, the thread can only be in the ready state after the set time (after the thread sleep ends, the thread may not execute immediately, but only enters the ready state, waiting for the system to schedule).
There are two points to note when using the sleep method:
1. The sleep method has two overloaded forms. One of the overloaded forms can not only set milliseconds, but also nanoseconds (1,000,000 nanoseconds is equal to 1 millisecond). However, the Java virtual machine on most operating system platforms is not accurate to nanoseconds. Therefore, if nanoseconds are set for sleep, the Java virtual machine will take the millisecond closest to this value.
2. When using the sleep method, throws or try{...}catch{...} must be used. Because the run method cannot use throws, you can only use try{...}catch{...}. When the thread is sleeping and the interrupt method is used to interrupt the thread, sleep will throw an InterruptedException. The sleep method is defined as follows:
There are three ways to terminate a thread.
1. Use the exit flag to make the thread exit normally, that is, the thread terminates when the run method is completed.
2. Use the stop method to forcefully terminate the thread (this method is not recommended because stop, like suspend and resume, may also produce unpredictable results).
3. Use the interrupt method to interrupt the thread.
1. Terminate the thread using the exit flag
When the run method is executed, the thread will exit. But sometimes the run method never ends. For example, threads are used in server programs to monitor client requests, or other tasks that require cyclic processing. In this case, these tasks are usually placed in a loop, such as a while loop. If you want the loop to run forever, you can use while(true){...} to handle it. But if you want to make the while loop exit under a certain condition, the most direct way is to set a boolean type flag, and set this flag to true or false to control whether the while loop exits. An example of terminating a thread using the exit flag is given below.
The function of the join method is to make asynchronous execution threads become synchronous execution. That is to say, when the start method of the thread instance is called, this method will return immediately. If you need to use a value calculated by this thread after calling the start method, you must use the join method. If you do not use the join method, there is no guarantee that when a statement following the start method is executed, the thread will be executed. After using the join method, the program will not continue execution until this thread exits. The following code demonstrates the use of join.
3. Multi-thread security issues
Cause of the problem: When multiple statements operate on the same thread and share data, one thread only executes part of the multiple statements. Before the execution is completed, another thread participates in the execution, resulting in shared data errors.
Solution: For multiple statements that operate on shared data, only one thread can be executed. During the execution process, other threads will not execute.
Synchronous code block:
}
}
}
}
public void run(){
while(true){
saleTicket();
}
}
}
Communication between threads
x=(x+1)%2;
}
}
}).start();
new Thread(new Runnable(){
public void run(){
while(true){
p.get();
}
}
}).start();
}
}
/*
Zhang San....Male Zhang San....Male
lili....nv
lili....male Zhang San....nv
lili....male
*/
}
}
}).start();
new Thread(new Runnable(){
public void run(){
while(true){
synchronized (p) {
p.get();
}
}
}
}).start();
}
}
/*
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
Zhang San....Male Zhang San....Male Zhang San....Male Zhang San....Male
*/
}
}
}).start();
new Thread(new Runnable(){
public void run(){
while(true){
synchronized (p) {
if(!flags)
try {
p.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
p.get();
flags =false;
p.notifyAll();
}
}
}
}).start();
}
}
}
final Goods g =new Goods();
new Thread(new Runnable(){
public void run(){
while(true){
g.produce("goods");
}
}
}).start();
new Thread(new Runnable(){
public void run(){
while(true){
g.consume();
}
}
}).start();
}
}
}
final Goods g =new Goods();
new Thread(new Runnable(){
public void run(){
while(true){
g.produce("goods");
}
}
},"Producer No.1").start();
new Thread(new Runnable(){
public void run(){
while(true){
g.produce("goods");
}
}
},"Producer No. 2").start();
new Thread(new Runnable(){
public void run(){
while(true){
g.consume();
}
}
},"Consumer No.1").start();
new Thread(new Runnable(){
public void run(){
while(true){
g.consume();
}
}
},"Consumer No. 2").start();
}
}
/*
Consumer No. 2 consumed ****** product number: 48049
Producer One produced....Item number: 48050
Consumer No. 1 consumed ****** product number: 48050
Producer One produced....Item number: 48051
Consumer No. 2 consumed ****** product number: 48051
Producer No.2 produced....Item number: 48052
Consumer No. 2 consumed ****** product number: 48052
Producer One produced....Item number: 48053
Consumer No. 1 consumed ****** product number: 48053
Producer One produced....Item number: 48054
Consumer No. 2 consumed ****** product number: 48054
Producer No.2 produced....Item number: 48055
Consumer No. 2 consumed ****** product number: 48055
*/