The key points of compiling and summarizing Java Multi-threaded program _java

Source: Internet
Author: User
Tags flushes instance method static class thread class volatile ticket

Thread state diagram

A thread consists of the following 5 states altogether.

1. New State (new): After the thread object is created, it enters the new state. For example, thread thread = new Thread ().

2. Ready state (Runnable): Also known as "executable state." When a thread object is created, the other thread invokes the object's start () method to start the thread. For example, Thread.Start (). A thread in the ready state may be scheduled to execute by the CPU at any time.

3. Running state (Running): The thread acquires CPU privileges to execute. It should be noted that the thread can only move from the ready state to the running state.

4. Blocking state (Blocked): Blocking state is the thread for some reason to give up the use of CPU, temporarily stop running. Until the thread enters the ready state, there is an opportunity to go to the running state. The blocking situation is divided into three types:

(01) Wait for blocking--by invoking the thread's Wait () method, the thread waits for the completion of a work.

(02) Synchronous blocking-the thread fails to acquire the synchronized synchronization lock (because the lock is occupied by another thread) and it enters the synchronized blocking state.

(03) Other blocking--the thread enters the blocking state by calling the thread's sleep () or join () or sending an I/O request. When the sleep () state times out, join () waits for the thread to terminate or timeout, or the I/O process completes, the thread is back in ready state.

5. State of Death (Dead): The thread has finished executing or exited the run () method because of an exception, which ends the lifecycle.

Thread and runnable to achieve multithreading
thread: Inheriting the thread class, implementing the Run method, calling the Start method in the main function to start the thread

Runnable: interface, implements the Runnable interface, passes as a parameter to the thread's constructor, and calls the Start method in main

Example:

Class Task implements Runnable {private int ticket = 10; @Override public void Run () {(int i = 0; i < i++) {if (This.ticket > 0) {SYSTEM.OUT.P
      Rintln (Thread.CurrentThread (). GetName () + "sold ticket" + this.ticket--);
 
 
}
    }
  }
 
};
    public class Runnabletest {public static void main (String[]args) {Task MyTask = new Task ();
    thread T1 = new Thread (mytask);
    Thread t2 = new Thread (mytask);
    thread t3 = new Thread (mytask);
    T1.start ();
    T2.start ();
  T3.start ();
 
  }//threadtest.java Source Class Mythread extends Thread {private int ticket = 10; public void Run () {for (int i = 0; i < i++) {if (This.ticket > 0) {System.out.println.
      GetName () + "Sell ticket: Ticket" + this.ticket--);
    The public class ThreadTest {public static void main (string[] args) {/) starts 3 threads t1,t2,t3; Each thread sells 10 tickets each!
    Mythread T1 = new Mythread (); Mythread t2 = new Mythread ();
    mythread t3 = new Mythread ();
    T1.start ();
    T2.start ();
  T3.start ();

 }
};


the difference between thread and runnable

Thread is a class, and runnable is an interface; thread itself is a class that implements the Runnable interface. We know that "a class can have only one parent class, but it can implement multiple interfaces", so runnable has better extensibility. In addition, runnable can also be used for "sharing resources." That is, multiple threads are based on a single Runnable object, and they share resources on the Runnable object. Generally, it is recommended to implement multithreading through "Runnable"!

Run and start of thread

Start (): Its function is to start a new thread, the new thread will execute the corresponding run () method. Start () cannot be called repeatedly. Start () actually starts the thread through the local method Start0 (). Start0 () will run a new thread, and the new thread will invoke the run () method.

Run (): Run (), like a normal member method, can be called repeatedly. Calling run () alone executes run () in the current thread and does not start a new thread! Run () is the run () method that invokes the runnable member of the thread thread directly, and does not create a new thread.

Demo.java source
class Mythread extends thread{public 
  mythread (String name) {
    super (name);
  }
 
  public void Run () {
    System.out.println (Thread.CurrentThread (). GetName () + ' is running ');
  } 
; 
 
public class Demo {public 
  static void Main (string[] args) { 
    Thread mythread=new mythread ("Mythread");
 
    System.out.println (Thread.CurrentThread (). GetName () + "Call Mythread.run ()");
    Mythread.run ();
 
    System.out.println (Thread.CurrentThread (). GetName () + "Call Mythread.start ()");
    Mythread.start ();
  } 

Output:

Main call Mythread.run ()
main are running
main call Mythread.start ()
Mythread is running


synchronized
in Java, where each object has a synchronous lock, when we call the object's synchronized method to acquire the object lock, synchronized (obj) acquires the "Obj object"  Synchronization lock. The access of different threads to the synchronization lock is mutually exclusive. A synchronization lock for a Point-in-time object can be acquired only by one thread. By synchronizing the locks, we can achieve mutually exclusive access to the object/method in multiple threads. For example, there are now two threads A and thread B that will access the synchronization lock for object obj. Suppose, at some point, thread a gets to "obj's Sync lock" and performs some action; at this point, thread B also attempts to get "obj's Sync lock"--thread B gets failed, and it must wait until thread a releases "Sync lock for this object" before thread B gets the "Sync Lock for obj" So that they can run.

Basic rules

First: When a thread accesses the synchronized method or synchronized code block of an object, access to that object's synchronized method or synchronized code block is blocked by other threads.

Second: When a thread accesses the "synchronized method" or "Synchronized code block" of "an object", other threads can still access the asynchronous code block of "that object".

Article three: When a thread accesses the "synchronized method" or "Synchronized code block" of "an object", other threads will block access to other "synchronized methods" or "synchronized code blocks" of the object.

Synchronized method

Public synchronized void Foo1 () {
  System.out.println ("synchronized methoed");
}
Synchronized code block public

void Foo2 () {  
    synchronized (this) {
    System.out.println ("synchronized methoed");
    }
}

This in the synchronized code block refers to the current object. You can also replace this with another object, such as replacing this with obj, Foo2 () acquires a synchronized lock for obj when executing synchronized (obj).

Synchronized code blocks allow more precise control of conflicts restrict access to areas and sometimes perform more efficiently

Instance locks and Global locks
instance Lock--locks on an instance object. If the class is a single case, then the lock also has the concept of global locks. The instance lock corresponds to the synchronized keyword.

Global lock--the lock is for a class and the thread shares the lock regardless of the number of instances of the instance. A global lock corresponds to a static synchronized (or a lock on the class or ClassLoader object).

Pulbic class Something {public  
  synchronized void Issynca () {} public  
  synchronized void Issyncb () {}  
  public static synchronized void Csynca () {} public  
  static synchronized void Csyncb () {}
}


() X.issynca () and X.ISSYNCB () cannot be accessed concurrently. Because Issynca () and ISSYNCB () are synchronized locks that access the same object (object x)!

X.issynca () and Y.issynca () can be accessed at the same time. Because the access is not a synchronous lock of the same object, X.issynca () accesses the sync lock of X, while Y.issynca () accesses the sync lock of Y.

() X.csynca () and Y.CSYNCB () cannot be accessed concurrently. Because Csynca () and CSYNCB () are static types, X.csynca () is the equivalent of Something.issynca (), Y.CSYNCB () is the equivalent of SOMETHING.ISSYNCB (), so they share a synchronous lock. cannot be asked at the same time.

() X.issynca () and Something.csynca () can be accessed concurrently. Because Issynca () is an instance method, X.issynca () uses the lock of Object X, and Csynca () is a static method, and Something.csynca () can understand the "Lock of Class" for use. Therefore, they can be accessed at the same time.


thread blocking and wake-up Wait,notify,notifyall
in Object.java, interfaces such as Wait (), notify (), and notifyall () are defined. The function of Wait () is to let the current thread into the waiting state, while the () will also let the current thread release the lock it holds. The role of Notify () and Notifyall () is to wake up the waiting thread on the current object, notify () is to wake up a single thread, and Notifyall () is to wake up all the threads.

The API details about wait/wake in the object class are as follows:

Notify ()--wakes up a single thread waiting on this object monitor.

Notifyall ()--wakes up all threads waiting on this object monitor.

Wait ()--leave the current thread in the waiting (blocking) state until the other thread calls the object's notify () method or Notifyall () method, and the current thread is awakened (into the ready state).

Wait (long timeout)--keeps the current thread in the waiting (blocking) state until the other thread calls the object's notify () method or Notifyall () method, or exceeds the specified amount of time ", the current thread is awakened (into the ready state).

Wait (long timeout, int nanos)--Leave the current thread in "Waiting (blocking) state" until another thread calls the object's notify () method or Notifyall () method, or some other thread interrupts the current thread. Or has exceeded a certain amount of actual time, the current thread is awakened (into the ready state).

Waittest.java source
class Threada extends thread{public
 
  Threada (String name) {
    super (name);
  }
 
  public void Run () {synchronized () {
      System.out.println thread.currentthread (). GetName () + "Call notify" () ");
      Wakes the current wait thread
      notify ();
 
}} public class Waittest {public
 
  static void Main (string[] args) {
 
    Threada t1 = new Threada ("T1");
 
    Synchronized (t1) {
      try {
        //start thread T1
        System.out.println (Thread.CurrentThread (). GetName () + "Start T1" );
        T1.start ();
 
        The main thread waits for T1 to be awakened by notify ().
        System.out.println (Thread.CurrentThread (). GetName () + "Wait ()");
        T1.wait ();
 
        System.out.println (Thread.CurrentThread (). GetName () + "continue");
      } catch (Interruptedexception e) {
        e.printstacktrace ();}}}

Output

Main start T1
main wait ()
T1 call notify ()
main continue

(01) Note that the "main thread" in the figure represents "main thread main". Thread T1 represents the thread T1 that is started in waittest. and "lock" represents "T1 this object's Sync lock".

(02) The "Main thread" creates a new "threading T1" through the new Threada ("T1"). The "T1 object's Sync lock" is then obtained via synchronized (T1). Then call T1.start () to start the thread t1.

(03) The "main thread" executes t1.wait () to release the "lock of the T1 object" and enter the "wait (blocking) state". Wait for the thread on the T1 object to wake it up by notify () or Notifyall ().

(04) after "Thread T1" is run, get "lock of current Object" by synchronized (this), then invoke notify () to wake up "wait thread on current object", that is, wake "main thread".

(05) After the "thread T1" has finished running, release the "lock of the current object." Next, the main thread gets the lock of the T1 object and then runs.

T1.wait () is the Wait () method called by thread T1, but the place where t1.wait () is invoked is in "main thread main". The main thread must be "current thread", which is the running state, before t1.wait () can be executed. So, at this point, the current thread is the main thread main! Therefore, t1.wait () is to let "main thread" wait, not "thread T1"!

Package Thread.
 
Test;
  public class Notifyalltest {private static Object obj = new Object ();
    public static void Main (string[] args) {Threada T1 = new Threada ("T1");
    Threada t2 = new Threada ("T2");
    Threada t3 = new Threada ("T3");
    T1.start ();
    T2.start ();
 
    T3.start ();
      try {System.out.println (Thread.CurrentThread (). GetName () + "sleep (3000)");
    Thread.Sleep (3000);
    catch (Interruptedexception e) {e.printstacktrace ();
      } synchronized (obj) {System.out.println (Thread.CurrentThread (). GetName () + "Notifyall ()");
      Obj.notifyall ()///This wake-up T1.T2.T3}} Static class Threada extends thread{public Threada (String name) {
    Super (name); public void Run () {synchronized (obj) {try {///PrintOut results System.out.println (thre
 
          Ad.currentthread (). GetName () + "Wait");
 
          Release obj object lock obj.wait (); Print Output System.out.println (thread.cuRrentthread (). GetName () + "continue");
        catch (Interruptedexception e) {e.printstacktrace ();

 }
      }
    }
  }
}

Output:

T1 wait
main sleep (3000)
t3 wait
T2 wait
main notifyall ()
T2 continue
T3 continue T1 Continue


(01) New and 3 Threads "T1", "T2" and "T3" are started in the main thread.

(02) The main thread sleeps 3 seconds through sleep (3000). While the main thread sleeps for 3 seconds, we assume that the 3 threads "T1", "T2" and "T3" are running. Take "T1" as an example, when it runs, it executes obj.wait () waits for other threads to wake it up by notify () or amount nofityall (), the same reason that "T2" and "T3" also wait for other threads to pass through nofity () or Nofityall () To awaken them.

(03) The main thread sleeps after 3 seconds, then runs. The execution Obj.notifyall () wakes up the wait threads on obj, that is, the 3 threads that wake up "T1", "T2" and "T3". Immediately after the main thread's synchronized (obj) runs, the main thread releases the obj lock. In this way, "T1", "T2" and "T3" can get "obj lock" and continue to run!

The relationship between Notify,notifyall and lock

The wait () in object, notify (), and the like synchronized, operate on the synchronized lock of the object.

Waiting () causes the current thread to wait because the thread is in the waiting state, so the thread should release the "Sync Lock" it holds, otherwise the other thread will not get the "sync lock" to run!

OK, after the thread calls wait (), it releases the "Sync lock" it holds, and, according to the previous introduction, we know that the waiting thread can be awakened by notify () or Notifyall (). Now, consider a question: what does notify () wake up to wait for threads on? Or, what is the connection between wait () waiting thread and notify ()? The answer is: "Synchronize locks on objects."

The thread that is responsible for waking the waiting thread (which we call the "wake-up thread"), it can wake up the wait thread only after obtaining the "sync Lock for this object" (where the sync lock must be the same as the waiting thread's sync lock) and calling the Notify () or Notifyall () method. Although the wait thread is awakened, it cannot be executed immediately because the wake thread also holds "synchronized locks on the object." You must wait until the wake thread frees the object's sync lock before the waiting thread can get to the object's sync lock to continue running.

In short, notify (), wait () depends on the "sync lock", while the "Sync Lock" is held by the object lock, and each object has and has only one! This is why the functions such as notify (), wait () are defined in the object class, not the thread class.


Thread Concessions yield
thread concessions, making the thread from the execution state to the ready state, this allows other waiting threads with the same priority to get execution rights, but there is no guarantee that after the current thread calls yield (), other threads with the same priority will be able to execute; it may also be that the current thread has entered the Run State "continues to run.

Yield and wait

(a) Wait () is to allow a thread to go from "Run state" to "Waiting (blocking)" state, without yield () to allow the thread to enter from "Run state" to the ready state.

Wait () is a synchronous lock in which the thread releases the object it holds, and the yield () method does not release the lock.

(=) Wait is the method of object, yield is the method of thread

Thread Hibernate sleep
the function of sleep () is to let the current thread hibernate, that is, the current thread will go from "Run state" to "hibernate (blocked) state". Sleep () Specifies the time of hibernation, when the thread sleeps longer than/equal to the sleep time; When the thread is awakened, it becomes "ready" by the blocking state, which waits for the CPU's dispatch to execute.

The difference between sleep and wait

The effect of Wait () is to allow the current thread to enter the waiting (blocking) state while the active state is running, releasing the sync lock as well. The function of sleep () is also to allow the current thread to enter the hibernate (blocking) state by running state. (This is not really the difference)

Wait () releases the synchronization lock of the object, while sleep () does not release the lock

Wait is the method of object, sleep is the method of thread

Join
let the main thread wait, the child thread is finished, the main thread will continue to run

Interrupt
used to terminate a thread in a blocked state

@Override public
Void Run () {a
  try {while
    (true) {
      //Execute task ...
    }
  catch (interruptedexception IE) { 
    //due to interruptedexception exception, exit while (true) loop, thread abort!
  }
}

In while (true), the interrupt () of the calling thread produces interruptedexception interrupts when the thread is in a blocked state. The interrupted capture is outside the while (true), which exits the while (true) loop

Terminate a thread in the running state

@Override public
Void Run () {while  
  (!isinterrupted ()) {    
  //Execute task ...  
  }
}

Common way to terminate a thread

@Override public
Void Run () {
  try {
    //1. isinterrupted () guarantee that the thread will terminate as long as the interrupt mark is true. While
    (!isinterrupted ()) {
      //Perform task ...
    }
  catch (Interruptedexception IE) { 
    //2. The interruptedexception exception guarantees that the thread is terminated when the interruptedexception exception is generated.
  }
}


Thread Priority
the range of thread priorities in Java is 1~10, and the default priority is 5. High priority threads take precedence over low priority threads. There are two kinds of threads in Java: The user thread and the daemon thread. They can be distinguished by the Isdaemon () method: If returned false, the thread is a user thread; User threads typically perform user-level tasks, and daemons are "background threads" that are typically used to perform background tasks. Note that the Java virtual machine exits after the user thread has finished.

Each thread has a priority level. High priority threads take precedence over low priority threads. Each thread can be marked as a daemon or a non daemon process. When a new child thread is created in some of the running main threads, the priority of the child thread is set to equal to the priority of the primary thread that created it, and the child thread is the daemon only if the main thread that created it is a daemon thread.

When a Java virtual machine is started, there is usually a single, non-daemon thread that is started through the main () method. The JVM will run until any one of the following conditions occurs, which terminates:

(01) The exit () method is invoked, and exit () has permission to execute normally.

(02) All "Non-daemon Threads" are dead (that is, the JVM only has "daemon threads").

Daemon process

(01) Main thread main is the user thread, it creates the child thread T1 is also the user thread.

(T2) is a daemon thread. When the main thread main and child thread T1 (both of which are user threads) are executed, the JVM automatically exits when only the T2 daemon is left.

Producer Consumer Issues
(01) The producer only when the warehouse is not full time production, the warehouse full will stop the production.

(02) Consumers can consume only when they have products in storage, while the Cang are waiting.

(03) When the consumer found that the storage is not available to consume when the producer will inform the production.

(04) Producers in the production of consumer products, should inform the waiting consumers to spend.

Communication between threads

Mode: Shared memory and message delivery

Shared memory: Thread A and thread B share memory, thread a updates the value of the shared variable, flushes to main memory, and thread B reads the variable after thread A is updated in main memory. The entire communication process must pass through main memory. Synchronization is done explicitly.

If a variable is a volatile type, the read and write to the variable will be atomic. In the case of multiple volatile operations or similar volatile++, these operations are not atomic in their entirety.

The volatile variable itself has the following attributes:

[Visibility]: For a volatile variable to read, it is always possible to see (any thread) the last write to the volatile variable.

[atomicity]: The read/write of any single volatile variable is atomic, but similar to volatile++ this composite operation is not atomic.

Volatile write: When you write a volatile variable, JMM flushes the shared variable in the local memory corresponding to the thread to the main memory.

Volatile read: When you read a volatile variable, jmm the corresponding local memory for that thread to be invalid. The thread then reads the shared variable from the main memory.

Message delivery: The message is sent synchronously implicitly before the message is accepted.

ThreadLocal

ThreadLocal is not used to solve the problem of multithreaded access to shared objects, in general, the objects in the thread are Threadlocal.set () to the thread, and other threads are not required to be accessed or accessed. Threadlocal allows each thread to maintain its own independent object, not by Threadlocal.set (), but by the action of the new object in each thread, which creates a copy or a copy of the object. by Threadlocal.set () a reference to this newly created object is saved to a map of each thread, each thread has such a map, and when the Threadlocal.get () is executed, each thread extracts the object that is placed in its own map. So the objects in their own threads are taken out, and the threadlocal instance is used as the key of the map. If Threadlocal.set () is in the same object that multiple threads share, the threadlocal.get () of multiple threads gets the shared object itself or has concurrent access problems.

An implementation of threadlocal

Import java.util.Collections; 
Import Java.util.HashMap; 
 
Import Java.util.Map; /** * uses the threadlocal class * * @author leizhimin 2010-1-5 10:35:27/public class Mythreadlocal {//defines a Threadlo Cal variable, used to hold int or Integer data private com.lavasoft.test2.threadlocal<integer> TL = new Com.lavasoft.test2.ThreadLoca 
        L<integer> () {@Override protected Integer InitialValue () {return 0; 
 
    } 
    }; 
        Public Integer Getnextnum () {///The TL value is fetched after 1, and the value of the set T1 is updated Tl.set (Tl.get () + 1); 
    return Tl.get (); } class Threadlocal<t> {Private Map<thread, t> Map = Collections.synchronizedmap (New hashmap<th 
 
    Read, t> ()); 
    Public ThreadLocal () {} protected T InitialValue () {return null; 
        Public T get () {Thread t = thread.currentthread (); 
        T obj = map.get (t); if (obj = = null &&!map.containskey (t)) {obj = iNitialvalue (); 
        Map.put (t, obj); 
    return obj; 
    public void Set (T value) {map.put (Thread.CurrentThread (), value); 
    public void Remove () {Map.Remove (Thread.CurrentThread ());
 } 
}

In fact, Threadlocal did this:

  Public T get () {
    Thread t = thread.currentthread ();
    Threadlocalmap map = getmap (t);
    if (map!= null) {
      Threadlocalmap.entry e = Map.getentry (this);
      if (e!= null) return
        (T) e.value;
    }
    return Setinitialvalue ();
  }

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.