Java High Concurrency Two: Multithreading Foundation detailed introduction _java

Source: Internet
Author: User
Tags deprecated garbage collection instance method static class stub thread class in python

This series is based on the gold course, in order to better study, do a series of records. This article mainly introduces 1. What is thread 2. Basic operation of threads 3. Thread priority 5. Basic thread Synchronization operations

1. What is a thread

A thread is an executing unit within a process

There are several threads in a process.

A thread is an execution unit within a process.

The reason for using threads is that process switching is a very heavyweight operation that consumes resources very much. If you use multiple processes, the number of concurrent numbers is relatively low. Threads are a smaller dispatch unit and are more lightweight, so threads are more widely used in concurrent design.

The concept of threads in Java and the concept of operating system-level threads are similar. In fact, the JVM will map threads in Java to the thread area of the operating system.

2. Basic operation of the thread

2.1 Thread state diagram

The diagram above is the basic operation of the Java thread.

When new comes out of a thread, the thread does not work. It simply generates an entity, and when you call the Start method of this instance, the thread is actually started. After booting to the runnable state, runnable indicates that the thread's resources, etc., have been prepared and ready to execute, but it does not mean that it must be in execution state, and that thread may not be executing at this time due to the rotation of the timeline. For us, the thread can assume that it has been executed, but whether it is true or not, it depends on the physical CPU scheduling. When the thread task execution is finished, the thread is in the terminated state.

Sometimes in the execution of a thread, it is unavoidable to apply for certain locks or the monitors of an object, and when it is not available, the thread will be blocked, suspended, and blocked state. If the thread calls the wait method, it is in a waiting state. The thread that enters the waiting state waits for the other thread to notify it, and the notification is then switched from the waiting state to the runnable state to continue execution. Of course there are two kinds of waiting states, one is waiting indefinitely until it is notify. have been waiting for a period of time, such as waiting for 10 seconds or not notify, then automatically switch to the runnable state.

2.2 New Threads

Thread thread = new Thread ();
Thread.Start ();

This opens a thread.
One thing to be aware of is that

Thread thread = new Thread ();
Thread.run ();

You cannot open a new thread by calling the Run method directly.

The Start method actually invokes the run method on top of a new operating system thread. In other words, calling the Run method directly instead of invoking the Start method does not open a new thread, but rather executes your operation in the current thread that calls run.

Thread thread = new Thread ("T1")
{
 @Override public
 Void Run ()
 {
 //TODO auto-generated method stub< C6/>system.out.println (Thread.CurrentThread (). GetName ());
 }
;
Thread.Start ();
If Start is invoked, the output is T1
thread thread = new Thread ("T1")
{@Override public
 void Run ()
 {
 // TODO auto-generated Method Stub
 System.out.println (Thread.CurrentThread (). GetName ());
 }
;
Thread.run ();

If run, the output is main. (direct call run is actually a normal function call, and does not achieve the role of multithreading)

There are two ways to implement the Run method

The first way to directly overwrite the Run method, as shown in the code just now, is to use an anonymous class that is most convenient to implement.

Thread thread = new Thread ("T1")
{
 @Override public
 Void Run ()
 {
 //TODO auto-generated method Stub
 System.out.println (Thread.CurrentThread (). GetName ());
 }
;

The second way

Thread T1=new Thread (new CreateThread3 ());

CreateThread3 () implements the Runnable interface.

In Zhang Xiaoxiang: video, the second method is recommended, which is more object-oriented.

2.3 Terminating a thread

Thread.stop () is not recommended for use. It will release all of the Monitor
In the source code has clearly stated that the Stop method is deprecated, in Javadoc also explained the reason.

The reason is that the stop method is too "violent" and will stop the thread immediately, no matter where it executes.

When the write thread gets the lock, writes the data, writes out ID = 1, and releases the lock when it is ready to stop the name = 1 o'clock. The read thread gets the lock for read, reads with an ID of 1, and name or 0, which results in inconsistent data.

The most important thing is that this error does not throw an exception and will be difficult to find.

2.4 Thread interrupts

There are 3 ways to thread interrupts

public void Thread.Interrupt ()//Interrupt Thread
public boolean thread.isinterrupted ()//Determine if interrupted
public static Boolean thread.interrupted ()//To determine if it is interrupted and to clear the current interrupt state

What is a thread interrupt?

If you do not understand the Java interrupt mechanism, such an explanation is highly misleading, thinking that the interrupt method that invokes the thread must break the thread.
In fact, Java interrupts are a collaborative mechanism. That is to say, the interrupt method of the calling thread object does not necessarily interrupt the running thread, it simply requires the thread to interrupt itself at the right moment. Each thread has a Boolean interrupt state (not necessarily the object's property, in fact, the state is not a field of thread), and the interrupt method simply resets the state to true. For a non-blocking thread, only the interrupt state is changed, that is, thread.isinterrupted () returns true and does not stop the program;

public void Run () {//thread T1 while
 (true) {
 Thread.yield ();
 }
}
T1.interrupt ();

This makes the thread T1 interrupted, and it does not work, except that the interrupt state bit is changed.

If you want to terminate this thread very gracefully, you should do so

public void Run () {while 
 (true)
 { 
 if (Thread.CurrentThread (). isinterrupted (
 )) { 
  System.out.println ("interruted!"); 
  break; 
 Thread.yield (); 
 } 

Using interrupts, there is a certain guarantee of data consistency.

For threads in a blocking state that can be canceled, such as the thread waiting on these functions, Thread.Sleep (), object.wait (), Thread.Join (), the thread receives the interrupt signal and throws interruptedexception. It also resets the interrupt state back to false.

For a thread in a blocking state, you can say code like this:

public void Run () {while
 (true) {
 if (Thread.CurrentThread (). isinterrupted ()) {System.out.println ()} (
  " Interruted! ");
  break;
 try {
  thread.sleep;
 } catch (Interruptedexception e) {
  System.out.println ("interruted when Sleep");
  //Set the interrupt state, and the interrupt mark bit
  will be cleared when an exception is thrown Thread.CurrentThread (). interrupt ();
 }
 Thread.yield ();
 }

2.5 Thread hangs

Suspend (suspend) and continue execution (resume) threads

Suspend () does not release locks

If the lock occurs before resume (), the deadlock occurs
Both of these methods are deprecated methods and are not recommended for use.

The reason is that suspend does not release the lock, so no thread can access the critical zone resource that it locks until it is resume by another thread. Because you cannot control the order in which threads run, if the resume method of other threads is run first, then the suspend that runs after it will always occupy this lock, causing the deadlock to occur.

Use the following code to simulate this scenario

Package test;

public class Test
{
 static Object u = new Object ();
 static Testsuspendthread T1 = new Testsuspendthread ("T1");
 static Testsuspendthread t2 = new Testsuspendthread ("T2");

 public static class Testsuspendthread extends Thread
 {public
 testsuspendthread (String name)
 {
 SetName (name);

 @Override public
 Void Run ()
 {
 synchronized (U)
 {
 System.out.println ("in" + GetName ());
 Thread.CurrentThread (). suspend ();

 public static void Main (string[] args) throws Interruptedexception
 {
 t1.start ();
 Thread.Sleep (m);
 T2.start ();
 T1.resume ();
 T2.resume ();
 T1.join ();
 T2.join ();
 }


Let t1,t2 at the same time for a lock, the thread suspend, and then resume, logically, should be a thread after the resume released the lock, then another thread for the lock, and then resume.
The resulting output is:

in T1
In T2

Description Two line Cheng Tu to the lock, but the red light of the console is still on, indicating that t1,t2 a certain thread has not finished. We dump out a heap to see

Found T2 has been suspend. This creates a deadlock.

2.6 Join and Yeild

Yeild is a native static method that wants to release the CPU time that it occupies and then compete with other threads (note that the yeild thread still has the potential to scramble to the CPU, noting that it differs from sleep). In Javadoc It is also explained that Yeild is a largely unused method, typically used in debug and test.

The Join method means waiting for the other thread to end, like the code in the Suspend section, to let the main thread wait for the t1,t2 to end. Without the end, the main thread would have been blocked there.

Package test;

public class Test
{public
 volatile static int i = 0;

 public static class Addthread extends Thread
 {
 @Override public
 Void Run ()
 {for
 (i = 0; I < 10000 000; i++)
 ;
 }

 public static void Main (string[] args) throws Interruptedexception
 {
 addthread at = new Addthread ();
 At.start ();
 At.join ();
 System.out.println (i);
 }
}

If you remove the at.join of the above code, the main thread will run directly and the value of I will be very small. If there is a join, the printed value of I must be 10000000.
So how does a join come true?

The nature of Join

while (IsAlive ())
{
Wait (0);
}

The join () method can also pass a time, meaning to wait for a limited time, and automatically wake up when it is over.
So there's a problem, who's going to notify this thread, and there's no place in the thread class that calls notify?

In Javadoc, the explanations are found. When a thread completes termination, the Notifyall method is invoked to wake up all threads waiting on the current thread instance, which is done by the JVM itself.

So Javadoc also gives us a suggestion not to use wait and notify/notifyall on the thread instance. Because the JVM will call on its own, it may be different from the result of the call you expect.

3. Daemon Threads

In the background silently to complete some of the systematic services, such as garbage collection thread, JIT thread can be understood as a daemon thread.
In a Java application, the Java virtual machine naturally exits when all the non-daemon processes are finished.
I've written a story about how to do this in Python, see here.

And it's relatively easy to become a daemon in Java.

Thread t=new Daemont ();
T.setdaemon (TRUE);
T.start ();

This opens a daemon thread.

Package test;

public class Test
{public
 static class Daemonthread extends Thread
 {
 @Override public
 void Run () c7/>{for
 (int i = 0; i < 10000000; i++)
 {
 System.out.println ("Hi");

 }} public static void Main (string[] args) throws Interruptedexception
 {
 daemonthread dt = new Daemonthread (); 
   dt.start ();
 }


When thread dt is not a daemon, after running, we can see the console output hi
When you join before start

Dt.setdaemon (TRUE);

The console simply exits, and there is no output.

4. Thread Priority

There are 3 variables in the thread class that define the thread priority.

 public final static int min_priority = 1; public final static int norm_priority = 5; pub
LIC final static int max_priority = 10;

Package test;
 public class Test {public static class High extends Thread {static int count = 0;
 @Override public void Run () {while (true) {synchronized (test.class) {count++;
 if (Count > 10000000) {System.out.println ("high");
 Break
 public static class Low extends Thread {static int count = 0;
 @Override public void Run () {while (true) {synchronized (test.class) {count++;
 if (Count > 10000000) {System.out.println ("low");
 Break
 }}}} public static void Main (string[] args) throws Interruptedexception {High high = new High ();
 Low low = new low ();
 High.setpriority (thread.max_priority);
 Low.setpriority (thread.min_priority);
 Low.start ();
 High.start (); }
}

Let a high priority thread and a low priority thread compete for a lock at the same time, and see which is the first to complete.
Of course not necessarily high priority must be done first. After running many times, it is found that the probability of high priority completion is relatively large, but low priority is still possible to finish first.

5. Basic Thread Synchronization operations

Synchronized and object.wait () obejct.notify ()

For more information on this section, please see a blog previously written

It's important to note that

There are three ways to lock the synchronized:

Specify the Lock object: Lock the given object and get the lock on the given object before entering the synchronization code.
Acts directly on an instance method: the equivalent of locking the current instance to get the current instance's lock before entering the synchronization code.
Works directly on static methods: the equivalent of locking the current class and getting the current class lock before entering the synchronization code.

Action on an instance method, do not new two different instances

Acting on a static method, as long as the class is OK, because the lock is a class. class, you can new two different instances.

Use of wait and notify:

Use what to lock, use what to call wait and notify

This article will not elaborate.

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.