Java thread Summary

Source: Internet
Author: User

First, we need to understand the thread. First, we need to understand some basic things. Most of the operating systems we use now belong to multi-task and time-based operating systems. It is precisely because of the emergence of such an operating system that the concept of multithreading exists. Linux, which we use, belongs to this column. What is a time-sharing operating system? In other words, it is equivalent to an operating system that can execute multiple programs at the same time. Are you listening to songs on your computer, while chatting, watching webpages? But in fact, the CPU does not execute these programs at the same time. The CPU only splits the time into time slices, and then allocates the time slice to these programs. The program that obtains the time slice starts to execute, the next program obtains the time slice and starts execution. As a result, multiple programs take turns to execute for a period of time, because of the high-speed computing capability of the CPU, it is like executing multiple programs at the same time.
Generally, an operating system that can execute multiple programs within the same time has the concept of a process. A process is an execution program, and each process has its own independent memory space and a group of system resources. in the process concept, the internal data and status of each process are completely independent. therefore, it can be imagined that the system that creates and executes a process is relatively large, so the thread appears. In Java, a program executes a program stream through throttling. The flow control in a single sequence in a program is called a thread, and multithreading means that multiple different threads can be run simultaneously in a single program, execute different tasks. multithreading means that multi-line statements of a program can run almost simultaneously at the same time. (You can replace the program in the previous sentence with a process. A process is an execution process of the program and the basic unit for running the program)

Similar to a process, a thread is a piece of code that completes a specific function. It is a flow control in a single sequence in the program. However, unlike a process, multiple threads of the same type share a piece of memory space and a group of system resources. The data of the thread itself is usually only the register data of the microprocessor and a stack used for program execution. therefore, when the system generates a thread or switches between threads, the burden is much lower than that of the process. For this reason, a thread is also called a light-weight process ). A process can contain multiple threads.

Multi-task means that a system can run multiple programs at the same time, that is, multiple tasks run independently. Each task corresponds to a process. Like a process, a thread is also created, the process of running to the extinction is called the life cycle of a thread. state indicates the stage in which the thread is in the life cycle. threads are created, runable, running, blocked, and dead. through thread control and scheduling, a thread can be converted between these States. Each program automatically owns at least one thread, which is called the main thread. when the program is loaded into the memory, the main thread is started.

[Thread running mechanism and scheduling model]
In Java, multithreading is the ability of a class or program to execute or manage multiple threads to execute tasks. Each thread can run independently of other threads. Of course, it can also run together with other threads, A class controls all its threads and determines which thread gets the priority, which thread can access other class resources, which thread starts to execute, and which remains sleep.
The following figure shows the thread mechanism:

The thread status indicates the ongoing activity of the thread and the tasks that can be completed within this period of time. threads are created, runable, running, blocked, and dead. A thread with life is always in one of the five states:
1. Creation status
After a thread is created using the new operator, the thread is only an empty object, and the system does not allocate resources, indicating that the thread is in the new thread state)
2. Running status
After a thread is started using the START () method, the system allocates resources other than the CPU for the thread to make it runnable)
3. Running status
The Java running system selects a runnable thread by scheduling to occupy the CPU and convert it to the running state (running). At this time, the system actually executes the run () method of the thread.
4. Blocking status
When a running thread cannot continue running for some reason, it enters the blocking status (BLOCKED)
5. Death
After the thread ends, it is in the dead state (dead)

If multiple threads are running at the same time, they need to queue for CPU resources. at this time, each thread automatically obtains the priority of a thread, which reflects the importance or urgency of the thread. running threads are queued by priority. Thread Scheduling is based on the "first come, first served" principle based on priority.
The thread scheduling manager is responsible for thread queuing and CPU allocation among threads, and is scheduled by the thread scheduling algorithm. when the thread scheduling manager selects a thread, the thread obtains CPU resources and enters the running state.

Thread Scheduling is a preemptible scheduling. If a thread with a higher priority enters the running state during the current thread execution, the thread is immediately scheduled for execution. preemptible scheduling includes exclusive scheduling and time-sharing scheduling.
In the exclusive mode, the current execution thread will continue to execute until the execution is completed or the CPU is automatically abandoned for some reason, or the CPU is preemptible by a higher-priority thread.
In the time-sharing mode, the current running thread obtains a time slice. When the time is reached, the CPU is transferred out even if the execution is not completed, and the system enters the running status, waiting for the scheduling of the next time slice. the system selects other runable threads for execution.
A time-sharing system allows each thread to work in several steps to run multiple threads simultaneously.

In addition, pay attention to the following Thread Scheduling rules (if you do not understand them, don't worry, please look down ):
① If two or more threads modify an object, define the method for executing the modification as synchronized. If the object update affects the read-only method, the degree-only method should also be defined as synchronous
② If a thread must wait for an object to change its state, it should wait inside the object, instead of waiting outside. It can call a synchronous method, and make this method call wait ()
③ Whenever a method changes the state of an object, it should call the notifyall () method, which gives the thread waiting for the queue the opportunity to see if the execution environment has changed
④ Remember that the wait (), Y (), and notifyall () Methods belong to the object class, rather than the Thread class. Check carefully to see if there is a corresponding notify () for each wait () method execution () or the notifyall () method, and they act as the same object in Java, each class has a main thread, to execute a program, then this class must have a main method, this man method is the main thread in Java class. You can create a thread by yourself. There are two methods: Inherit the Thread class or implement the runnable interface. In general, it is best to avoid inheritance because Java contains a single inheritance. If you choose inheritance, your class will lose elasticity, and of course you cannot completely deny the inheritance thread, this method is easy to write and can be used to operate threads directly. It is suitable for single-inheritance. The specific analysis of the specific situation is as follows.

Eg. inherit from thread

public class MyThread_1 extends Thread
{
public void run()
{
//some code
}
}

Eg. Implement the runnable interface

public class MyThread_2 implements Runnable
{
public void run()
{
//some code
}
}

When the inheritance creation thread is used, start the thread as follows:

new MyThread_1().start()

When using the implementation interface to create a thread, start the thread as follows:

new Thread(new MyThread_2()).start()

Note that it is actually to create a thread instance and pass in the instance with the class implementing the runnable interface as the parameter. When this thread is executed, the code in run in mythread_2 will be executed.
The following is an example:

public class MyThread implements Runnable
{

public void run()
{
System.out.println("My Name is "+Thread.currentThread().getName());
}
public static void main(String[] args)
{
new Thread(new MyThread()).start();
}
}

After execution, it will print out:
My name is thread-0

You can also create multiple threads, as shown below

new Thread(new MyThread()).start();
new Thread(new MyThread()).start();
new Thread(new MyThread()).start();

The output is as follows:
My name is thread-0
My name is thread-1
My name is thread-2

After reading the above results, you may think that the thread execution sequence is sequential, but that is only the general situation. Never use it as the thread execution mechanism; there are several factors that affect the thread execution sequence: first, let's take a look at the priority level mentioned above.

Public class mythread implements runnable
{

Public void run ()
{
System. Out. println ("My name is" + thread. currentthread (). getname ());
}
Public static void main (string [] ARGs)
{
Thread T1 = new thread (New mythread ());
Thread t2 = new thread (New mythread ());
Thread T3 = new thread (New mythread ());
T2.setpriority (thread. max_priority); // assign the highest priority
T1.start ();
T2.start ();
T3.start ();
}
}

Let's look at the results:
My name is thread-1
My name is thread-0
My name is thread-2

The thread priority is divided into 10 levels, which are represented by an integer ranging from 1 to 10. The default value is 5. The above t2.setpriority (thread. max_priority) is equivalent to t2.setpriority (10)
Then there is the design of the thread program itself, such as using sleep, yield, join, wait and other methods (for details, see jdkdocument)

Public class mythread implements runnable
{
Public void run ()
{
Try
{
Int sleeptime = (INT) (math. Random () * 100); // generates random numbers,
Thread. currentthread (). Sleep (sleeptime); // Let it sleep for a certain period of time, which is determined by sleeptime above
// Public static void sleep (long millis) Throw interruptedexception (API)
System. Out. println (thread. currentthread (). getname () + "sleeping" + sleeptime );
} Catch (interruptedexception IE) // catch exceptions when calling the sleep method because the thread may be interrupted during sleep.
{
Ie. printstacktrace ();
}
}
Public static void main (string [] ARGs)
{
Thread T1 = new thread (New mythread ());
Thread t2 = new thread (New mythread ());
Thread T3 = new thread (New mythread ());
T1.start ();
T2.start ();
T3.start ();
}
}

Observe its output after execution:

Thread-0 sleeping 11
Thread-2 sleeping 48
Thread-1 sleep 69

The preceding execution results are random, and different results may occur after execution. Since I have added a sleep statement in run, when the thread is sleep, it will give up the CPU, and the CPU will choose to execute other threads in the runnable state. Of course, this may also happen, the sleeping thread immediately enters the runnable state, and the CPU executes it again.
[Thread group concept]
A thread can be organized. Java has the concept of a thread group. Each thread is a member of a thread group. A thread group integrates multiple threads into an object, multiple Threads in a thread group can be operated at the same time, such as starting all threads in a thread group. java thread groups are composed of Java. the implementation of the thread-group class in the lang package.
The threadgroup class is used to manage a group of threads, including the number of threads, the relationship between threads, the operations being executed by the threads, and the time when the threads will be started or terminated. A thread group can also contain a thread group. in Java applications, the thread group at the highest level is the main thread group, and can also be added to the main thread or thread group, you can also add threads and thread groups to the sub-thread group of Mian to form a tree inheritance relationship between the thread group and the thread. The threads created above belong to the main thread group.
Using the example above, the main can be written as follows:

public static void main(String[] args)
{
/***************************************
ThreadGroup(String name)
ThreadGroup(ThreadGroup parent, String name)
***********************************/
ThreadGroup group1=new ThreadGroup("group1");
ThreadGroup group2=new ThreadGroup(group1,"group2");
Thread t1=new Thread(group2,new MyThread());
Thread t2=new Thread(group2,new MyThread());
Thread t3=new Thread(group2,new MyThread());
t1.start();
t2.start();
t3.start();
}

Thread group nesting. T1, T2, and T3 are added to Group2 and group2 to group1.
The other is mostly about thread synchronization. Imagine that you have a deposit in a bank, and you have a deposit in a bank for your account, your wife withdraws money from this account in another bank. Now you have 1000 yuan in your account. You saved 1000, but since the other party is still operating on the deposit, when people start to execute the deposit, they only see the original 1000 yuan in the account. When your wife withdraws 1000 yuan, your wife's bank thinks you have no money in your account, but your bank thinks you still have 2000 yuan.
Take a look at the following example:

Class blanksaving // savings account
{
Private Static int money = 10000;
Public void add (int I)
{
Money = money + I;
System. Out. println ("husband deposit [¥" + I + "]" to the Bank);
}
Public void get (int I)
{
Money = money-I;
System. Out. println ("wife took [¥" + I + "]" to the Bank);
If (money <0)
System. Out. println ("insufficient balance! ");
}
Public int showmoney ()
{
Return money;
}
}


Class operater implements runnable
{
String name;
Blanksaving BS;
Public operater (blanksaving B, string S)
{
Name = s;
BS = B;



}
Public static void encrypt (string name, blanksaving BS)
{



If (name. Equals ("husband "))
{
Try
{
For (INT I = 0; I <10; I ++)
{
Thread. currentthread (). Sleep (INT) (math. Random () * 300 ));
BS. Add (1, 1000 );
}
} Catch (interruptedexception e ){}
} Else
{
Try
{



For (INT I = 0; I <10; I ++)
{
Thread. currentthread (). Sleep (INT) (math. Random () * 300 ));
BS. Get (1, 1000 );
}
} Catch (interruptedexception e ){}
}
}
Public void run ()
{
Aggregate (name, BS );
}
}
Public class banktest
{
Public static void main (string [] ARGs) throws interruptedexception
{
Blanksaving BS = new blanksaving ();
Operater O1 = new operater (BS, "husband ");
Operater O2 = new operater (BS, "wife ");
Thread T1 = new thread (O1 );
Thread t2 = new thread (O2 );
T1.start ();
T2.start ();
Thread. currentthread (). Sleep (500 );
}



}

The following is the execution result:

--------- First --------------
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Husband has deposited [¥1000] into the bank

As you can see, this is not the correct requirement. When husband is not finished, wife inserts it, which may lead to unexpected results. The solution is simple, that is, to declare the data operation method as synchronized. When the method is declared by this keyword, it means that if the data is locked, only when an object gets the lock of the data can the object operate on the data. That is, when you make a deposit, this account cannot be operated elsewhere. Only after the deposit is completed, the bank administrator can unlock the account, and other talents can operate on the account.
Modify public static void encrypt (string name, blanksaving BS) to public static void encrypt (string name, blanksaving BS), and then look at the result:

Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Husband has deposited [¥1000] into the bank
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]
Wife took it to the bank [¥1000]

After the husband completes the operation, the wife starts the operation. In this way, the operation on the shared object will not be a problem.
[Wait and policy]
You can use these two methods to control the thread execution process. When the thread calls the wait method, the thread will be suspended until it is awakened by another thread (wait Y) or, if the wait method specifies a time, the wait method will automatically wake up after the specified time when it is not awakened. However, it must be noted that the wake-up operation does not mean immediate execution, but changes from the group congestion status to the operational status. Whether the wake-up operation is running depends on CPU scheduling.
Example code:

class MyThread_1 extends Thread
{
Object lock;
public MyThread_1(Object o)
{
lock=o;
}
public void run()
{
try
{
synchronized(lock)
{
System.out.println("Enter Thread_1 and wait");
lock.wait();
System.out.println("be notified");
}
}catch(InterruptedException e){}
}
}
class MyThread_2 extends Thread
{
Object lock;
public MyThread_2(Object o)
{
lock=o;
}
public void run()
{
synchronized(lock)
{
System.out.println("Enter Thread_2 and notify");
lock.notify();
}
}
}
public class MyThread
{
public static void main(String[] args)
{
int[] in=new int[0];//notice
MyThread_1 t1=new MyThread_1(in);
MyThread_2 t2=new MyThread_2(in);
t1.start();
t2.start();
}
}

The execution result is as follows:
Enter thread_1 and wait
Enter thread_2 and 127y
Thread_1 be notified

You may have noticed that when using the wait and ipvy methods, I used the synchronized block to wrap these two methods. This is because the thread must obtain the lock when calling these two methods, that is, the lock [] in the above Code. If you don't need synchronized to wrap the two methods, or the lock may not be the same, for example, synchronized (LOCK) in mythread_2) to synchronized (this), Java will be thrown during execution of this program. lang. illegalmonitorstateexception exception during execution. In addition, the wait and notify methods are in the object and are not in the Thread class. Finally, you may have noticed this: int [] In = new int [0]; why is it not creating a new object but an array of 0 length, this is because it is more efficient to create a zero-length array in Java to act as a lock.

As an important part of Java, thread also requires a deeper understanding in many places. The above is just a brief summary of some common sense and error problems of thread, to really master Java threads, you also need to make a summary on your own.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.