Java Concurrency Programming Example (ix): Use of local thread variables _java

Source: Internet
Author: User
Tags thread class

Shared data is one of the most critical features of concurrent programs. This is a very week-important aspect for objects that inherit from the thread class, or for objects that implement the Runnable interface.

If you create an object for a class that implements the Runnable interface and use that object to start a series of threads, all of these threads share the same properties. In other words, if a thread modifies a property, all the remaining threads will be affected by this change.

Sometimes, we prefer to use the agenda online instead of sharing it with other threads that start with the same object. The Java Concurrency interface provides a clear mechanism to meet this requirement, which is called a local thread variable. The performance of this mechanism is also very considerable.

Know it

Follow the steps shown below to complete the sample program.

1. First, the implementation of a procedure with the above problems. Create a class named Unsafetask and implement the Runnable interface. Declares a private property of a java.util.Date type in a class. The code is as follows:

Copy Code code as follows:

public class Unsafetask implements Runnable {
Private Date StartDate;

2. Implement the Unsafetask Run () method, which instantiates the StartDate property and outputs its value to the console. Hibernate randomly for a period of time, and then output the value of the StartDate property to the console again. The code is as follows:

Copy Code code as follows:

@Override
public void Run () {
StartDate = new Date ();
System.out.printf ("Starting Thread:%s:%s\n",
Thread.CurrentThread (). GetId (), startdate);

try {
TimeUnit.SECONDS.sleep ((int) math.rint (math.random () * 10));
catch (Interruptedexception e) {
E.printstacktrace ();
}

System.out.printf ("Thread finished:%s:%s\n",
Thread.CurrentThread (). GetId (), startdate);
}

3. The main class that implements the problem program. Create a class with the main () method, Unsafemain. In the main () method, create a Unsafetask object and use the object to create 10 thread objects to start 10 threads. In the middle of each thread, hibernate for 2 seconds. The code is as follows:

Copy Code code as follows:

public class Unsafemain {
public static void Main (string[] args) {
Unsafetask task = new Unsafetask ();
for (int i = 0; i < i++) {
Thread thread = new thread (Task);
Thread.Start ();
try {
TimeUnit.SECONDS.sleep (2);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
}

4. From the above logic, each thread has a different start time. However, according to the output log below, many of the same time values appear. As follows:

Copy Code code as follows:

Starting Thread:9: Sun Sep 23:31:08 CST 2013
Starting Thread:10:sun Sep 23:31:10 CST 2013
Starting Thread:11:sun Sep 23:31:12 CST 2013
Starting Thread:12:sun Sep 23:31:14 CST 2013
Thread finished:9: Sun Sep 23:31:14 CST 2013
Starting Thread:13:sun Sep 23:31:16 CST 2013
Thread Finished:10:sun Sep 23:31:16 CST 2013
Starting Thread:14:sun Sep 23:31:18 CST 2013
Thread Finished:11:sun Sep 23:31:18 CST 2013
Starting Thread:15:sun Sep 23:31:20 CST 2013
Thread Finished:12:sun Sep 23:31:20 CST 2013
Starting Thread:16:sun Sep 23:31:22 CST 2013
Starting Thread:17:sun Sep 23:31:24 CST 2013
Thread Finished:17:sun Sep 23:31:24 CST 2013
Thread Finished:15:sun Sep 23:31:24 CST 2013
Thread Finished:13:sun Sep 23:31:24 CST 2013
Starting Thread:18:sun Sep 23:31:26 CST 2013
Thread Finished:14:sun Sep 23:31:26 CST 2013
Thread Finished:18:sun Sep 23:31:26 CST 2013
Thread Finished:16:sun Sep 23:31:26 CST 2013

5. As indicated above, we are prepared to use the local thread variable (the thread-local variables) mechanism to resolve this problem.

6. Create a class named Safetask and implement the Runnable interface. The code is as follows:

Copy Code code as follows:

public class Safetask implements Runnable {

7. Declares an object of a threadlocal<date> type that, when instantiated, overrides the InitialValue () method, in which the actual date value is returned. The code is as follows:
Copy Code code as follows:

private static threadlocal<date> StartDate = new
Threadlocal<date> () {
@Override
Protected Date InitialValue () {
return new Date ();
}
};

8. Implement the Run () method of the Safetask class. This method, like the Unsafetask Run () method, is just a slight adjustment to the way the StartDate property is used. The code is as follows:

Copy Code code as follows:

@Override
public void Run () {
System.out.printf ("Starting Thread:%s:%s\n",
Thread.CurrentThread (). GetId (), Startdate.get ());

try {
TimeUnit.SECONDS.sleep ((int) math.rint (math.random () * 10));
catch (Interruptedexception e) {
E.printstacktrace ();
}

System.out.printf ("Thread finished:%s:%s\n",
Thread.CurrentThread (). GetId (), Startdate.get ());
}

9. The main class of the security example and the main class of the Unsafetask program are basically the same, except that you need to modify it to safetask. The specific code is as follows:

Copy Code code as follows:

public class Safemain {
public static void Main (string[] args) {
Safetask task = new Safetask ();
for (int i = 0; i < i++) {
Thread thread = new thread (Task);
Thread.Start ();
try {
TimeUnit.SECONDS.sleep (2);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
}

10. Run the program to analyze the difference of two inputs.

For the purpose of canonical class naming, the main class in this article has a slightly different naming and text. In addition, the original procedure and the text narration are inconsistent. It should be a clerical error.

Know the reason why

The following is the result of the security example execution. From the results, it is easy to see that each thread has a StartDate property value that belongs to the respective thread. The program is entered as follows:

Copy Code code as follows:

Starting Thread:9: Sun Sep 23:52:17 CST 2013
Starting Thread:10:sun Sep 23:52:19 CST 2013
Starting Thread:11:sun Sep 23:52:21 CST 2013
Thread Finished:10:sun Sep 23:52:19 CST 2013
Starting Thread:12:sun Sep 23:52:23 CST 2013
Thread Finished:11:sun Sep 23:52:21 CST 2013
Starting Thread:13:sun Sep 23:52:25 CST 2013
Thread finished:9: Sun Sep 23:52:17 CST 2013
Starting Thread:14:sun Sep 23:52:27 CST 2013
Starting Thread:15:sun Sep 23:52:29 CST 2013
Thread Finished:13:sun Sep 23:52:25 CST 2013
Starting Thread:16:sun Sep 23:52:31 CST 2013
Thread Finished:14:sun Sep 23:52:27 CST 2013
Starting Thread:17:sun Sep 23:52:33 CST 2013
Thread Finished:12:sun Sep 23:52:23 CST 2013
Thread Finished:16:sun Sep 23:52:31 CST 2013
Thread Finished:15:sun Sep 23:52:29 CST 2013
Starting Thread:18:sun Sep 23:52:35 CST 2013
Thread Finished:17:sun Sep 23:52:33 CST 2013
Thread Finished:18:sun Sep 23:52:35 CST 2013

A thread-local variable stores a copy of a property for each thread. You can use the threadlocal get () method to obtain the value of a variable, using the Set () method to set the value of the variable. If the thread-local variable is first accessed and the variable has not yet been assigned, the InitialValue () method is invoked to initialize a value for each thread.

Endless

The Threadlocal class also provides a remove () method that deletes the value of the local variable stored in the thread that called the method.

In addition, the Java Concurrency API provides a inheritablethreadlocal class that allows child threads to receive the initial values of all inheritable thread-local variables to obtain the values that the parent thread has. If thread A has a thread-local variable, and when thread a creates thread B, thread B will have the same thread-local variables as thread A. You can also override Childvalue () to initialize the thread-local variables of the child thread. The method will accept the value of the thread-local variable passed from the parent thread as a parameter.

Copycat

This article is from the "Java 7 Concurrency Cookbook" (D-Gua to "Java7 concurrent Sample Set") translation, only as learning materials used. No authorization shall be applied to any commercial act.

Small has become

The following is a full version of all the code contained in the example in this section.

Complete code for the Unsafetask class:

Copy Code code as follows:

Package com.diguage.books.concurrencycookbook.chapter1.recipe9;

Import Java.util.Date;
Import Java.util.concurrent.TimeUnit;

/**
* No guarantee of thread safety examples
* date:2013-09-23
* time:23:58
*/
public class Unsafetask implements Runnable {
Private Date StartDate;

@Override
public void Run () {
StartDate = new Date ();
System.out.printf ("Starting Thread:%s:%s\n",
Thread.CurrentThread (). GetId (), startdate);

try {
TimeUnit.SECONDS.sleep ((int) math.rint (math.random () * 10));
catch (Interruptedexception e) {
E.printstacktrace ();
}

System.out.printf ("Thread finished:%s:%s\n",
Thread.CurrentThread (). GetId (), startdate);
}
}

Complete code for the Unsafemain class:

Copy Code code as follows:

Package com.diguage.books.concurrencycookbook.chapter1.recipe9;

Import Java.util.concurrent.TimeUnit;

/**
* Unsafe Threads sample
* date:2013-09-24
* time:00:04
*/
public class Unsafemain {
public static void Main (string[] args) {
Unsafetask task = new Unsafetask ();
for (int i = 0; i < i++) {
Thread thread = new thread (Task);
Thread.Start ();
try {
TimeUnit.SECONDS.sleep (2);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
}

Complete code for the Safetask class:

Copy Code code as follows:

Package com.diguage.books.concurrencycookbook.chapter1.recipe9;

Import Java.util.Date;
Import Java.util.concurrent.TimeUnit;

/**
 * use thread-local variables to guarantee thread security
 * date:2013-09-29
 * time:23:34
 */
public class Safet Ask implements Runnable {
    private static threadlocal<date> StartDate = new
  & nbsp;         threadlocal<date> () {
                 @Override
                 protected Date InitialValue () {
                     return new Date ( );
               }
           };

@Override
public void Run () {
System.out.printf ("Starting Thread:%s:%s\n",
Thread.CurrentThread (). GetId (), Startdate.get ());

try {
TimeUnit.SECONDS.sleep ((int) math.rint (math.random () * 10));
catch (Interruptedexception e) {
E.printstacktrace ();
}

System.out.printf ("Thread finished:%s:%s\n",
Thread.CurrentThread (). GetId (), Startdate.get ());
}
}

Complete code for the Safemain class:

Copy Code code as follows:

Package com.diguage.books.concurrencycookbook.chapter1.recipe9;

Import Java.util.concurrent.TimeUnit;

/**
* Secure Threading Sample
* date:2013-09-24
* time:00:04
*/
public class Safemain {
public static void Main (string[] args) {
Safetask task = new Safetask ();
for (int i = 0; i < i++) {
Thread thread = new thread (Task);
Thread.Start ();
try {
TimeUnit.SECONDS.sleep (2);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
}


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.