Java thread Memory model, thread, working memory, main memory

Source: Internet
Author: User
Tags visibility

Go from: http://rainyear.iteye.com/blog/1734311java Thread memory model

Interaction diagram between threads, working memory, and main memory:

Key Edeas

All threads share the main memory each thread has its own working memory refreshing the local memory To/from main memories must comply to JMM rules

Reasons for thread safety

The working memory of a thread is an abstract description of the Cpu's registers and caches: now the computer, the CPU in the calculation, not always read from memory, its data reading order priority Is: Register-cache-memory. The thread consumes the cpu, the thread calculates the raw data from the memory, during the calculation, some data may be read frequently, the data is stored in registers and caches, when the thread is calculated, the cached data should be written back to memory when Appropriate. Multi-threaded concurrency problems arise when multiple threads read and write to one memory data at the same time, involving three features: atomicity, ordering, and Visibility. This is a problem for platforms that support multithreading, and languages that support multithreading on multithreaded platforms should provide a solution to the Problem.

The JVM is a virtual computer, it will also face multi-threaded concurrency problems, Java programs run on the Java Virtual machine platform, Java programmers can not directly control the underlying thread to register cache memory synchronization between, then Java from the syntactic level, should provide developers with a solution, This scheme is such as synchronized, volatile, lock mechanism (such as synchronization block, ready queue, blocking Queue) and so On. These programs are only grammatical, but we need to understand them in nature;

Each thread has its own execution space (that is, working memory), The execution of the thread to use a variable, the first to copy the variables from the main memory of their own working memory space, and then the variables to operate: read, modify, assignment, and so on, these are in the working memory is completed, and then write the variables back to the main memory;

Each thread obtains data from main memory, the data between threads is not visible; for example, the main memory variable A has a raw value of 1, thread 1 takes the variable a from main memory, modifies A's value to 2, and thread 1 does not write the variable a back to main memory, and threads 2 Gets the value of variable A is still 1;

This leads to the concept of "visibility": when a shared variable has a copy in the working memory of multiple threads, if a thread modifies the copy value of the shared variable, then other threads should be able to see the modified value, which is the problem of multi-threaded Visibility.

Normal variable situation: If thread a modifies the value of an ordinary variable and then writes back to the main memory, another thread B reads the thread A after the Write-back is completed, and then the value of the new variable is visible to threads b;

How to ensure thread safety
Writing Thread-safe code is essentially managing access to States (state), and is often a shared, mutable state. The state here is the variable of the object (static variable and instance Variable)
The premise of thread safety is whether the variable is accessed by multiple threads, ensuring that the thread security of the object requires synchronization to coordinate access to its mutable state, and that if this is not done, it can result in dirty data and other unexpected Consequences. Whenever more than one thread accesses the given State variable, and one of the threads writes to the variable, synchronization must be used to reconcile the Thread's access to the Variable. The primary synchronization mechanism in Java is the synchronized keyword, which provides an exclusive LOCK. In addition, The term "synchronization" also includes volatile variables, showing the use of locks and atomic Variables.
In the absence of proper synchronization, if multiple threads access the same variable, your program has a hidden problem. There are 3 ways to fix it:
L do not share variables across threads;
L make the state variable immutable;
L use synchronization in any access state variable.

Volatile requires the program to each modification of the variable, all write back to the main memory, so that the other threading courseware, to solve the problem of visibility, but does not guarantee the consistency of the data; special note: Atomic operations: Depending on the Java specification, the assignment or return value operation for the base type is Atomic. But the basic data types here do not include long and double because the JVM sees the basic storage unit is 32 bits, and long and double are represented by 64 Bits. So it can't be done in one clock cycle.

In Layman's terms, the state of an object is its data, stored in a state variable, such as an instance field or a static domain, whenever more than one thread accesses a given State variable. And one of the threads writes to the variable, and synchronization must be used to coordinate the Thread's access to the variable;

Sync Lock: Each Java object has only one synchronization lock, and at any given time, only one thread is allowed to have this lock.

When a thread attempts to access a block of code with the synchronized (this) tag, it must obtain the lock of the object referenced by the This keyword, which has a different fate in the following two Cases.
1, If the lock is already occupied by other threads, the JVM will put this thread into the lock pool of this Object. This thread goes into a blocking State. There may be many threads in the lock pool, and when other threads release the lock, the JVM randomly pulls a thread out of the lock pool, causes the thread to have the lock, and goes to the ready State.
2, If this lock is not occupied by other threads, this thread will get the lock and begin to execute the synchronous code BLOCK.
(in general, synchronization locks are not released when you execute a synchronous code block, but there are special cases where object locks are released
If an exception is encountered while executing a synchronous code block, the lock is freed, and when the code block executes, the wait () method of the object to which the lock belongs is executed, which frees the object lock and enters the Object's waiting Pool.

The Synchronized keyword guarantees data read-write consistency and visibility, but he is a blocking Thread-control method that all other threads cannot use during the keyword use, which leads to a requirement to control thread safety called Non-blocking Synchronization.

ThreadLocal parsing

As the name implies, it is local variable (thread local variable). Its function is very simple, that is, each thread that uses the variable provides a copy of the value of a variable, and each thread can independently change its own copy without conflicting with the other Thread's copy. From a thread's point of view, It's as if every thread has exactly the Variable.

Each thread maintains an implicit reference to a copy of its Thread's local variables, as long as the thread is active and the ThreadLocal instance is accessible, and all copies of its thread-local instance are garbage-collected after the threads have disappeared (unless there are other references to those replicas).

Object wait () and notify () method parsing

The wait () and notify (), Notifyall () methods of object, use an object as a lock, and then call wait () to suspend the current thread while releasing the object lock;

Notify () use to get the object lock first before waking the suspended thread (because it waits for an object lock to Hang)

Notifyall (): wakes all the threads waiting on this object Monitor.

Wait () causes the current thread to wait before another thread calls the notify() method or method of this object notifyAll() .

thrown: IllegalMonitorStateException -if the current thread is not the owner of this object monitor

Package Com.taobao.concurrency;public class Waittest {public static String a = "";//as monitor object public static void Mai        N (string[] Args) throws interruptedexception {waittest wa = new Waittest ();        Testtask task = wa.new testtask ();        Thread t = new Thread (task);        T.start ();        Thread.Sleep (12000);            for (int i = 5; i > 0; i--) {System.out.println ("fast wakeup of suspended thread ************");        Thread.Sleep (1000); } System.out.println ("roger, now!        Wake up the suspended thread ************ ");        Synchronized (a) {a.notifyall ();                }} class Testtask implements Runnable {@Override public void run () {synchronized (a) {                        Try {for (int i = ten; i > 0; i--) {thread.sleep (1000);                    System.out.println ("i'm Running ***************");                    } a.wait ();             for (int i = ten; i > 0; i--) {           System.out.println ("thank you for waking ********** and starting to run the *******");                }} catch (interruptedexception e) {e.printstacktrace (); }            }        }    }}

Resolve producer consumer problem codes with wait notify:

Package Com.taobao.concurrency;import Java.util.concurrent.executorservice;import java.util.concurrent.Executors;    Import Java.util.concurrent.timeunit;class Meal {private final int ordernum;    Public Meal (int Ordernum) {this.ordernum = ordernum;    } public String toString () {return ' Meal ' + ordernum;    }}class Waitperson implements Runnable {private Restaurant Restaurant;    Public Waitperson (Restaurant R) {this.restaurant = r; } @Override public void run () {try {while (!                        thread.interrupted ()) {synchronized (this) {while (restaurant.meal = = Null) Wait ();//.                For the chef to produce a meal} System.out.println ("waitperson got" + restaurant.meal);                    Synchronized (restaurant.chef) {restaurant.meal = null;   Restaurant.chef.notifyAll ();//ready for another}}         TimeUnit.MICROSECONDS.sleep (100);        } catch (interruptedexception E) {System.out.println ("waitperson interrupted");    }}}class Chef implements Runnable {private Restaurant Restaurant;    private int count = 0;    Public Chef (Restaurant R) {this.restaurant = r; } @Override public void run () {try {while (!                        thread.interrupted ()) {synchronized (this) {while (restaurant.meal! = Null)                    Wait ();//... for the meal-be taken} if (++count = = 10) {                    System.out.println ("out of food,closing");                Restaurant.exec.shutdownNow ();                } System.out.println ("Order up!");                    Synchronized (restaurant.waitperson) {restaurant.meal = new Meal (count);                Restaurant.waitPerson.notifyAll (); }}} Catch (interrupTedexception E) {}}}public class Restaurant {Meal Meal;    Executorservice exec = Executors.newcachedthreadpool ();    Waitperson Waitperson = new Waitperson (this);    Chef chef = new chef (this);        Public Restaurant () {exec.execute (chef);    Exec.execute (waitperson);    } public static void main (string[] Args) {new Restaurant (); }}

Using Arrayblockingqueue to solve the problem of producer consumers; The default is to use a non-fair lock

Take (): takes the Blockingqueue in the first row of the object, if the blockingqueue is empty, blocking into the waiting state until blocking a new object is added, if the request is not added to this thread is joined the blocking queue;

If a fair lock is used, when there is content to consume, the consumer thread is taken out of the queue for consumption (that is, the thread waiting for the longest time)

Add (anobject): add AnObject to blockingqueue, that is, if Blockingqueue can accommodate, return true, otherwise recruitment exception

Package Com.taobao.concurrency;import Java.util.concurrent.arrayblockingqueue;import Java.util.concurrent.blockingqueue;public class testblockingqueues {public static void main (string[] Args) {Bl        ockingqueue<string> queue = new Arrayblockingqueue<string> (20);        Thread Pro = new thread (new Producer (queue), "producer");        Pro.start ();            for (int i = 0; i < i++) {thread t = new Thread (new concumer (queue), "consumer" + i);        T.start ();    }}}class Producer implements Runnable {blockingqueue<string> queue;    Public Producer (blockingqueue<string> Queue) {this.queue = queue;        } @Override public void run () {int i = 0;                While (true) {try {System.out.println ("producer produces food, food number:" + i);                Queue.put ("food" + i++);            Thread.Sleep (1000);            } catch (interruptedexception E) {System.out.println ("producer interrupted"); }       }}}class Concumer implements Runnable {blockingqueue<string> queue;    Public Concumer (blockingqueue<string> Queue) {this.queue = queue; } @Override public void run () {while (true) {try {System.out.println (thread.curr            Entthread (). getName () + "consumption:" + queue.take ());            } catch (interruptedexception E) {System.out.println ("consumer interrupted"); }}} to execute the result:

Consumer 0 Request Consumption
Consumer 2 Request consumption
Consumer 4 Request consumption
Consumer 6 Request consumption
Consumer 8 Request consumption
Consumer 5 Request consumption
Producers produce food, food Number: 0
Consumer 0 consumption: Food 0
Consumer 1 Request consumption
Consumer 3 Request consumption
Consumer 7 Request consumption
Consumer 9 Request consumption
Consumer 0 Request Consumption
Producers produce food, food Number: 1
Consumer 2 consumption: Food 1
Consumer 2 Request consumption
Producers produce food, Food Number: 2
Consumer 4 consumption: Food 2
Consumer 4 Request consumption
Producers produce food, Food Number: 3
Consumer 6 consumption: Food 3
Consumer 6 Request consumption
Producers produce food, Food Number: 4
Consumer 8 consumption: Food 4
Consumer 8 Request consumption
Producers produce food, Food Number: 5
Consumer 5 consumption: Food 5
Consumer 5 Request consumption
Producers produce food, Food Number: 6
Consumer 1 consumption: Food 6
Consumer 1 Request consumption
Producers produce food, Food Number: 7
Consumer 3 consumption: Food 7
Consumer 3 Request consumption
Producers produce food, Food Number: 8
Consumer 7 consumption: Food 8
Consumer 7 Request consumption
Producers produce food, Food Number: 9
Consumer 9 consumption: Food 9
Consumer 9 Request consumption


Multiple producers, multiple consumers

Package Com.taobao.concurrency;import Java.util.concurrent.arrayblockingqueue;import Java.util.concurrent.blockingqueue;public class testblockingqueues {public static void main (string[] Args) {Bl        ockingqueue<string> queue = new Arrayblockingqueue<string> (20);            for (int i = 0; i < i++) {thread Pro = new Thread (new Producer (queue), "producer" + i);        Pro.start ();            } for (int i = 0; i < i++) {thread t = new Thread (new concumer (queue), "consumer" + i);        T.start ();    }}}class Producer implements Runnable {blockingqueue<string> queue;    Public Producer (blockingqueue<string> Queue) {this.queue = queue;        } @Override public void run () {int i = 0;                            While (true) {try {System.out.println (thread.currentthread (). getName ()           + "produce food, Food number:" + thread.currentthread (). getName ()                 + i);                    Queue.put ("food" + thread.currentthread (). getName () + i++);                           Thread.Sleep (10000);            } catch (interruptedexception E) {System.out.println ("producer interrupted");    }}}}class Concumer implements Runnable {blockingqueue<string> queue;    Public Concumer (blockingqueue<string> Queue) {this.queue = queue;  } @Override public void run () {while (true) {System.out.println (thread.currentthread (). getName ()            + "request for consumption");                Try {System.out.println (thread.currentthread (). getName () + "consumption:" + queue.take ());            Thread.Sleep (100);            } catch (interruptedexception E) {System.out.println ("consumer interrupted"); }}}} producer 0 produce food, food number: producer 00 Producer 2 produce food, food number: producer 20 producer 1 produce food, food number: producer 10 producer 3 produce food, food number: producer 30 producer 4 produce food, food Number: producer 40 born Production of 6 food, food number: producer 60 producer 8 produce food, food number: producer80 producer 5 produce food, food number: producer 50 producer 7 produce food, food number: producer 70 producer 9 produce food, food number: producer 90 consumer 0 request consumer consumer 0 consumption: food producer 00 Consumer 2 request Consumer consumer 2 consumption: food producer 20 Consumer 1 Request Consumer consumer 1 consumption: food producer 10 Consumer 4 request consumer consumer 4 consumption: food producer 30 consumer 3 request consumer consumer 6 request consumer consumer 6 consumption: food producer 40 Consumer 3 consumer: food producer 60 Consumer 8 request consumer consumer 8 consumption : Food producer 80 Consumer 5 request consumer consumer 5 consumption: food producer 50 consumer 7 request consumer consumer 7 consumption: food producer 70 consumer 9 request consumer consumer 9 consumption: food producer 90 consumer 0 request consumer consumer 1 request Consumer consumer 2 request consumer Fee 4 requests Consumer consumer 3 requests consumer consumer 5 requests consumer consumer 7 requests consumer consumer 9 requests Consumer consumer 6 requests consumer consumption 8 to request consumer product 0 to produce food, food number: producer 01 consumer 0 consumption: Food producer 01 Producer 2 produces food, food number is : Producer 21 Producer 4 produces food, food number: producer 41 Consumer 1 consumption: food producer 21 producer 1 produce food, food number: producer 11 Consumer 2 consumption: food producer 41 Consumer 4 consumption: food producer 11 producer 3 produce food, food number: producer 31

Conditional Queue Interpretation:

Condition queues is like the ' toast is ready ' bell on your toaster. If you were listening for it, you were notified promptly when your toast was ready and can drop what do you be doing (or not, m Aybe want to finish the newspaper First) and get your Toast. If you aren't listening for it (perhaps you went outside to get the newspaper), you could miss the notification, but on R Eturn to the kitchen your can observe the state of the toaster and either retrieve the toast if It's finished or start LIS Tening for the bell again if it isn't.

Condition-based: multi-threaded case, a condition at some point is false, does not mean that it has been false, may be a moment to good!

The default for lock is a non-fair lock; the condition object inherits the common characteristics of the lock associated with it, and if it is a fair lock, the thread is freed from the condition.wait in the order of the fifo; There is a relatively bad place in the arrayblockingqueue, the producers should inform the consumers after each Production.

Java thread Memory model, thread, working memory, main memory

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.