Talk about concurrent Programming (ii): Java Threading creation and basic control

Source: Internet
Author: User
Tags terminates

creation of Java threads Defining TasksUsing in JavaTaskThis noun is a code snippet that represents a thread control flow, using the RunnableInterface to mark a task, the Run method of the interface is the code snippet that the thread executes.
public class LiftOff implements Runnable {     protected int countdown = ten;     private static int taskcount = 0;     private final int id = taskcount++;     public void Run () {while          (countdown--> 0) {               System.out.print ("#" +id+ "(" +countdown+ "). ");                              Thread.yield ();}}}     
Thread.yield () is a recommendation to the thread scheduler at the time of invocation, meaning that it is now willing to voluntarily discard the CPU time slice and make it available to other threads. Now we use this class.
public class Mainthread {public     static void Main (string[] args) {          LiftOff lauch = new LiftOff ();          Lauch.run ();     }}
The above usage is to invoke the run method of the class object directly in the main thread, instead of creating a new thread to perform the task. To implement threading behavior, you must explicitly attach a task to the thread. Use the thread class in Java to create a thread.
public class Basicthreads {public     static void Main (string[] args) {          thread t = new Thread (new LiftOff ());          T.start ();          System.out.println ("Waiting for LiftOff");}     }
A thread can only have one task, but a task may be executed by multiple threads. When a task is executed by multiple threads, the member objects within that task are also shared by multiple threads. Such as:
public class Morebasicthreads {public     static void Main (String args[]) {          LiftOff LiftOff = new LiftOff ();          for (int i = 0; i < 5; i++) {               new Thread (LIFTOFF). Start ();}}     }
You can see that the output is very weird: the order is reversed, and the "5" disappears directly. This is because the gap between the countdown and the output is inserted by other threads, and there is a problem with the visibility of the Taskcount variable (the JVM optimizes it so that each operation is not all in memory, so the state of the variables seen by each thread is inconsistent). Each time the program runs differently, this phenomenon is called thread racing.     In a later article, we'll show you how to securely collaborate between threads. (Here, no longer describes the way to define tasks and start threads by inheriting the thread, because that way is limited by issues such as inheritance and the inability of threads to share resources within tasks.) ) ExecutorJDK5 provides us with the executor (thread Executor) tool to help us manage threads, and with this tool we can efficiently manage multiple threads. There are three kinds of executor commonly used in the practice. using Cachedthreadpool's executorCachethreadpool will create a thread for each task, with no upper limit on the number of threads in the thread pool. If a thread in the thread pool runs at the end, the thread will be recycled by thread pools waiting for the next creation of a new thread to be used. Cases:
public class Cachedthreadpool {public     static void main (String []args) {          Executorservice exec = Executors.newcach Edthreadpool ();          for (int i = 0; i < 5; i++)                Exec.execute (New LiftOff ());          Exec.shutdown ();}}
/*output:(Sample) #1 (9). #1 (8). #1 (7). #1 (6). #1 (5). #1 (4). #3 (9). #4 (9). #2 (9). #0 (9). #2 (8). #4 (8). #3 (8). #3 (7). #3 (6). #3 (5). #3 (4). #3 (3). #3 (2). #3 (1). #3 (0). #1 (3). #4 (7). #4 (6). #4 (5). #2 (7). #2 (6). #0 (8). #0 (7). #0 (6). #0 (5). #0 (4). #0 (3). #0 (2). #0 (1). #0 (0). #4 (4). #1 (2). #4 (3). #1 (1). #4 (2). #1 (0). #4 (1). #4 (0). #2 (5). #2 (4). #2 (3). #2 (2). #2 (1).      #2 (0). A call to the shutdown () method prevents the new task from being submitted to this executor, but the submitted task continues to run until it is completed.
using Fixedthreadpool's executorFixedthreadpool will pre-customize the size of the thread pool (number of threads), that is, when the thread pool is created, the threads are allocated, and the number of threads is no longer allowed to expand. Using such a thread pool can perform a one-time job of expensive thread assignment and avoid abusing threads. To create a thread example:
public class fixedthreadpool{public     static void main (String []args) {          Executorservice exec = Executors.fixedthreadpool ();          for (int i = 0; i < 5; i++)                Exec.execute (New LiftOff ());          Exec.shutdown ();     }}

SinglethreadexecutorThe executor uses only one thread, which is like a fixedthreadpool with a number of 1 threads. If you submit multiple tasks to Singlethreadexecutor, those tasks will be queued, each task will run at the end of the next task, and all the tasks would use the same thread.
public class Singlethreadexecutor {public     static void main (String []args) {          Executorservice exec = executors.new Singlethreadexecutor ();          for (int i = 0; i < 5; i++)                Exec.execute (New LiftOff ());          Exec.shutdown ();     }}

/*output: #0 (9). #0 (8). #0 (7). #0 (6). #0 (5). #0 (4). #0 (3). #0 (2). #0 (1). #0 (0). #1 (9). #1 (8). #1 (7). #1 (6). #1 (5). #1 (4). #1 (3). #1 (2). #1 (1). #1 (0). #2 (9). #2 (8). #2 (7). #2 (6). #2 (5). #2 (4). #2 (3). #2 (2). #2 (1). #2 (0). #3 (9). #3 (8). #3 (7). #3 (6). #3 (5). #3 (4). #3 (3). #3 (2). #3 (1). #3 (0). #4 (9). #4 (8). #4 (7). #4 (6). #4 (5). #4 (4). #4 (3). #4 (2). #4 (1). #4 (0).
Singlethreadexecutor can provide some degree of concurrency assurance that if a task is executed only by that type of exector, then there is no problem with threading. For logically independent tasks, rather than performance requirements that require threading, it is not a choice to use the executor to manage threads.
generate a return value from a taskRunnable is a standalone task when performing a job, but it does not return any values. If you want the task to return a value when it is finished, use the callable interface instead of the Runnable interface. Callable is a generic with a type parameter, and its type parameter represents the value returned from the method call () (instead of Run ()) and must be called with the Executorservice.submit () method, and here is an example:
Class Taskwithresult implements callable<string> {private int id;     public taskwithresult (int id) {this.id = ID;     } @Override public String call () throws Exception {return "result of Taskwithresult" + ID; }}public class Callabledemo {public static void main (string[] args) {Executorservice exec = Executors.newca          Chedthreadpool ();          arraylist<future<string>> results = new arraylist<future<string>> ();          for (int i = 0; i < 10;i++) {Results.add (Exec.submit (New Taskwithresult (i)));               } for (future<string> fs:results) try {System.out.println (Fs.get ());               } catch (Interruptedexception e) {System.out.println (e);               } catch (Executionexception e) {System.out.println (e);     } exec.shutdown (); }}

The submit () method produces a future object that is parameterized with a specific type of callable return result. You can use the Isdone () method to query whether the future has been completed. When the task finishes, it has a result, and you can call the Get () method to get the result. You can call get () directly without checking the Isdone () method, in which case get () will block until the result is ready.     You can also call get () with a timeout before attempting to get the result (), or call the Isdone () method to see if the task is complete. For callable you should know two points: 1. The objects or data generated by a thread created using runnable are typically managed with additional objects, while data or objects generated using callable can be managed without additional object management, and the results of the thread execution are returned directly through the Get method of the future. 2. The Get method of the resulting future object has blocking characteristics, so you can use this method to do some cooperative operations, so as to avoid introducing some other synchronization facilities, such as atomic lock.
HibernateThe Thread.Sleep (long) function allows the thread that invokes the function to hibernate, in milliseconds. In addition to this approach, you can also timeunit classes for sleep, such as TimeUnit.MILLISECONDS.sleep (1000), which allows you to specify a time unit for sleep () delay, thus providing better readability.
Priority Level      Thread priority passes the thread's importance to the scheduler. The scheduler will tend to execute the highest priority threads first, with lower priority threads executing less frequently. In most of the time, all threads should run with the default priority. Trying to manipulate thread priority is usually an error. Examples are as follows:
public class Simplepriorities implements runnable{private int countdown = 5;     private double D;     private int priority;     Public Simplepriorities (int.) {this.priority = priority;     } public String toString () {return thread.currentthread () + ":" + countdown;          public void Run () {Thread.CurrentThread (). SetPriority (priority);                while (true) {for (int i = 1; i < 100000; i++) {D + = (Math.PI + MATH.E)/(double) I;          if (i% = = 0) Thread.yield ();          } System.out.println (this);     if (--countdown = = 0) return;          }} public static void Main (string[] args) {Executorservice exec = Executors.newcachedthreadpool ();               for (int i = 0; i < 5; i++) Exec.execute (new Simplepriorities (thread.min_priority));               Exec.execute (New Simplepriorities (thread.max_priority)); Exec.sHutdown (); }}
/output:thread[pool-1-thread-6,10,main]: 5thread[pool-1-thread-4,1,main]: 5thread[pool-1-thread-6,10,main]: 4thread[pool-1-thread-6,10,main]: 3thread[pool-1-thread-6,10,main]: 2thread[pool-1-thread-3,1,main]: 5Thread[    Pool-1-thread-4,1,main]: 4thread[pool-1-thread-2,1,main]: 5 ..... ..... ................ The Thread.tostring () method is used in the preceding code to print the name of the thread, the priority of the thread, and the thread group to which the thread belongs. You can use the constructor to set this name, which is the auto-generated name.     In addition, a reference to the current thread can be obtained by Thread.currrentthread (). Although the JDK has 10 priorities, it does not map well with most operating systems because the precedence rules for each system are different. The only way to migrate is when you adjust the priority, only themax_priority, norm_priority, and Min_priorityThree different levels.
ConcessionUsing the yield () method can give a hint to the thread scheduling mechanism: Your work has been done pretty much, allowing other threads to use the CPU (but this is just a hint that there is no mechanism to ensure that it will be accepted).     When yield is called, you are also recommending that other threads with the same priority be able to run. Using Thread.yield () can often produce well-distributed processing mechanisms. However, in general, yield () cannot be relied upon for any important control or adjustment of the application. In fact, yield () is often misused.
Background ThreadCalled Backstage (daemon)A thread is a thread that provides a generic service in the background while the program is running, and this thread is not an integral part of the program. Therefore, when all non-background threads end, the program terminates and kills all the background threads in the process. For example, executing main () is a non-background thread.
public class Simpledaemons implements Runnable {public     void run () {          try{while               (true) {                    TimeUnit.MILLISECONDS.sleep (+);                    System.out.println (Thread.CurrentThread () + "" +this);               }          } catch (Interruptedexception e) {               System.out.println ("Sleep () interrupted");          }     }     public static void Main (String []args] throws Exception {for          (int i = 0; i <; i++) {               Thread daemon = new T Hread (New Simpledaemons ());               Daemon.setdaemon (true);               Daemon.start ();          }          System.out.println ("All daemons started");          TimeUnit.MILLISECONDS.sleep (175);     }}  

/* Output: (Sample) all daemons startedthread[thread-0,5,main] [email protected]thread[thread-7,5,main] [email Protected]thread[thread-2,5,main] [email protected]thread[thread-5,5,main] [email protected]thread[thread-3,5,main [Email Protected]thread[thread-6,5,main] [email protected]thread[thread-9,5,main] [email protected]thread[thread-1 , 5,main] [email protected]thread[thread-4,5,main] [email protected]thread[thread-8,5,main] [email protected]
The Setdaemon () method must be called before a thread is started before it can be set as a background thread. If we are going to generate a lot of background threads, you can use Threadfactory to customize the properties (background, priority, name) of the thread created by executor:
public class Daemonthreadfactory implements threadfactory{public Thread Newthread (Runnable r) {Thread t = N          EW Thread (R);          T.setdaemon (TRUE);     return t;               }} public class Daemonfromfactory implements Runnable {@Override public void run () {try{                    while (true) {TimeUnit.MILLISECONDS.sleep (100);               System.out.println (Thread.CurrentThread () + "" +this);          }} catch (Interruptedexception e) {System.out.println ("interrupted"); }} public static void Main (String args[]) throws Exception {Executorservice exec = Executors.newcachedt          Hreadpool ();          for (int i = 0; i < i++) Exec.execute (New Daemonfromfactory ());          System.out.println ("All daemons started");     TimeUnit.MILLISECONDS.sleep (500); }}
You can determine whether a thread is a background thread by calling the Isdaemon () method of the Thread object, and if it is a background thread, any threads it creates will be automatically set to a background thread. The finally clause of a background thread may not be executed. When the last non-background thread terminates, the background thread "suddenly" terminates. Therefore, once main () exits, the JVM will immediately close all background processes without any confirmation form that you wish to appear.
Join a threadOne thread can call the join () method on another thread, and the effect is to wait for a period of time until the second thread finishes.     If a thread is T.join () on another thread T, the thread will be suspended until the target thread T ends (T.isalive () is returned as false). You can also take a time-out parameter (in milliseconds, or nanoseconds) when the join () is called, and the Join () method always returns if the target thread has not finished at this time.
Catching exceptions      Because of the intrinsic nature of the thread, you cannot catch an exception that escapes from the thread. Once the run () method of an exception escapes the task, it is propagated outward to the console, unless you take special steps to catch the exception of this error, using executor to solve the problem.       To solve this problem, we want to modify the way executor generates threads. Thread.uncaughtexception-handler is the interface introduced by Jdk5.0, which allows you to attach an exception handler on each thread object. Thread.UncaughtExceptionHandler.uncaughtException () is called when the thread is near death due to an uncaught exception. To use it, we create a new type of threadfactory that will attach a thread.uncaughtexceptionhandler to each newly created thread object. We pass this factory to executors to create a new Executorservice method:
Class ExceptionThread2 implements Runnable {public void run () {Thread t = thread.currentthread ();          System.out.println ("Run () by" + t);          System.out.println ("eh =" + T.getuncaughtexceptionhandler ());     throw new RuntimeException (); }}class Myuncaughtexceptionhandler implements Thread.uncaughtexceptionhandler {public void uncaughtexception (Thread t     , Throwable e) {System.out.println ("caught" + e); }}class Handlerthreadfactory implements Threadfactory {public Thread newthread (Runnable r) {System.out.prin          TLN (this + "creating new Thread");          Thread t = new Thread (r);          System.out.println ("created" + t);          T.setuncaughtexceptionhandler (New Myuncaughtexceptionhandler ());          System.out.println ("eh =" + T.getuncaughtexceptionhandler ());     return t; }}public class Captureuncaughtexception {public static void main (String []args) {Executorservice exec = Exe Cutors.neWcachedthreadpool (New Handlerthreadfactory ());     Exec.execute (New ExceptionThread2 ()); }}

/* Output:[email protected] Creating new threadcreated Thread[thread-0,5,main]eh = [email Protected]run () by Thread[threa D-0,5,main]eh = [email protected]caught java.lang.RuntimeException The above example allows you to set up the processor individually, depending on the situation. If you know that you want to use the same exception handler everywhere in your code, the easier way is to set up a static domain in the thread class and set the processor as the default uncaught exception handler:
public class Settingdefaulthandler {public     static void Main (string[] args) {          Thread.setdefaultuncaughtexceptionhandler (               new Myuncaughtexceptionhandler ());          Executorservice exec = Executors.newcachedthreadpool ();          Exec.execute (New Exceptionthread ());     
This processor is called only if there is no exception handler that is not caught by the thread. The system checks the proprietary version of the thread, and if it is not found, checks whether the thread group has a proprietary Uncaughtexception () method, and if not, calls Defaultuncaughtexceptionhandler.


Talk about concurrent Programming (ii): Java Threading creation and basic control

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.