7 Multi-Threading

Source: Internet
Author: User
Tags finally block thread class

Multithreading

1. Compared to multi-process, the advantages of multithreading are:

(1)进程之间不能共享数据,线程可以;(2)系统创建进程需要为该进程重新分配系统资源,故创建线程代价比较小;

2. Create a thread and start (3 types)

(1) Inherit the thread class, overriding the Run () method (with anonymous class) thread thread = new Thread () {public void Run () {}; } t.start (); (2) Implement Runnable interface, rewrite the Run method two ways: anonymous: Runnable task = new Runnable () {public void              Run () {}};               Thread t = new thread (Task);        T.start ();            Lambda expression Runnable task = (), {System.out.println ("HelloWorld");            }; Thread t = new Thread (Task), (3) Create thread callable with callable and future features: 1. You can have a return value of 2. The method of the interface throws exception if the task master    The body has an exception, can not be processed, the system automatically processes the use of callable steps: 1. Create an instance of callable callable<string> call = () {return "xxx";}; 2. Packaged as a futuretask (implementation of the future and Runable interface)//Futuretask of the generic parameters, must be the same as the callable generic parameters require the same type, compatible type Futuretask<stri    ng> task = new futuretask<> (call);    3. Futuretask as a task, passed to the thread of the constructor thread T = new thread (Task); 4. The start party of the calling threadLaw T.start (); 

3. Thread Life cycle
(1), new status

用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。通过调用start方法进入就绪状态(runnable)。注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常。

(2), Ready state

处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它称为可运行池而不是可运行队列。因为cpu的调度不一定是按照先进先出的顺序来调度的),等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“cpu调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。提示:如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep()方式使主线程睡眠一会儿,转去执行子线程。

(3), operating status

处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务。如果该线程失去了cpu资源,就会又从运行状态变为就绪状态。重新等待系统分配资源。也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。注: 当发生如下情况时,线程会从运行状态变为阻塞状态:①、线程调用sleep方法主动放弃所占用的系统资源 ②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞 ③、线程试图获得一个同步监视器,但更改同步监视器正被其他线程所持有 ④、线程在等待某个通知(notify) ⑤、程序调用了线程的suspend方法将线程挂起。不过该方法容易导致死锁,所以程序应该尽量避免使用该方法。当线程的run()方法执行完,或者被强制性地终止,例如出现异常,或者调用了stop()、desyory()方法等等,就会从运行状态转变为死亡状态。

(4), blocking state

 处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。有三种方法可以暂停Threads执行:

(5), death status

When the thread's run () method finishes executing, or is forced to terminate, it is considered dead. This thread object may be alive, but it is not a separate thread. Once a thread dies, it cannot be resurrected. If you call the start () method on a dead thread, the java.lang.IllegalThreadStateException exception is thrown. **4. Thread Management * * (1) thread sleep--sleep thread.sleep (1000);            (2) Thread concession--yield Thread.yield (); Set Priority: Thread.setpriority (1); Note: The difference between the sleep () method and the yield () side is as follows: ①, the Sleep method pauses the current thread, it goes into a blocking state, and only when the sleep time is reached will it go into a ready state.      After the yield method is called, it is directly into the ready state, so it is possible to just enter the ready state and be dispatched to the running state. The ②, sleep method declaration throws a interruptedexception, so the sleep method is called to catch the exception, or the display declares that the exception is thrown.      The yield method does not declare a thrown task exception.     The ③ and sleep methods are more portable than the yield method, and generally do not rely on the yield method to control the execution of concurrent threads.                  (3) Thread merge--join (Thread.Join ()) merges threads of several parallel threads into one single-threaded execution, and the scenario is that there are three overloaded methods when one thread must wait for another thread to execute to execute:                      void join () waits for the thread to terminate after the current thread has joined the thread. void join (Long Millis) The current thread waits for the thread to terminate for a maximum of millis milliseconds.  If the thread is not finished executing during the Millis time, then when the front-end goes into a ready state, wait for the CPU dispatch void join (long millis,int Nanos) to wait for the thread to terminate for the longest time Millis milliseconds + Nanos nanoseconds. If the thread has not finished executing during the Millis time, then when the front-end goes into a ready state, wait for the CPU schedule (4) To set the priority of the thread (THREAD.SETPRiority (1)) high-priority threads have a higher probability of acquiring CPU resources, and the lower priority is not a chance to execute.       The default priority for each thread has the same priority as the parent thread that created it, and by default, the main thread has a normal priority. Note: The thread class provides the setpriority (int newpriority) and getpriority () methods to set and return the priority of a specified thread, where the parameters of the SetPriority method are an integer, the range is 1~ 0,   You can also use the three static constants provided by the thread class: Max_priority =10 min_priority =1 norm_priority                          =5 class MyThread extends Thread {public MyThread (String Name,int Pro) { Super (name);//Set thread name SetPriority (PRO);//Set Thread priority} @                       Override public void Run () {for (int i = 0; i <; i++) { System.out.println (This.getname () + "line Cheng Di" + i + "time to execute!                          ");  }}} public class Test1 {public static void main (string[] args) Throws Interruptedexception {new MyThread ("Advanced", "ten"). Start ();               New MyThread ("Low", 1). Start ();                }} (5) background (daemon) process--thread.setdaemon (TRUE);        The thread object is set to a background thread, and this method must be called before start ().        Background threads are primarily used to maintain and monitor tasks. After all non-background threads have finished, the program ends. At this point, if there is still a background thread executing, all the background threads end and break directly. (6) Correct end thread Discard method Thread.stop (); Thread.Suspend ();       Thread.Resume (); ① normally executes the run method, then ends it, ② controls the loop condition and the identifier of the judging condition to end the thread.

5. Thread synchronization (Sync Lock)

多线程并发时,多个线程同时操作一个可共享的资源时,将会导致数据不准确。      (1)同步方法     既有synchronized关键字修饰的方法。由于java每一个对象都有一个内置锁,当用此关键字修饰方法时,     内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则处于阻塞状态。     注:synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。  (2)同步代码块   既有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。  注:同步是一种高开销的操作,因此应尽量减少同步的内容。  (3)使用重入锁(Lock)实现线程同步       ReentrantLock类是可重入、互斥、实现了Lock接口的锁。       ReentrantLock() : 创建一个ReentrantLock实例                       lock() : 获得锁                      unlock() : 释放锁       class Bank {        private int account = 100;        //需要声明这个锁        private Lock lock = new ReentrantLock();        public int getAccount() {            return account;        }        //这里不再需要synchronized         public void save(int money) {            lock.lock();            try{                account += money;            }finally{                lock.unlock();            }        }    }

6. Thread communication (producer and consumer)

(1), with the help of the object class Wait (), notify () and Notifyall () to achieve communication

After the thread executes wait (), it discards the run qualification, freezes, and when the thread runs, a pool of threads is created in memory, and the frozen state of the thread is present in the thread pool, and notify () wakes the thread in the thread pool when it executes, and wakes up the first frozen thread when there are multiple threads in the thread pool. Notifyall (), wakes all threads in the thread pool.  Note: ①wait (), notify (), Notifyall () are used in synchronization, because these 3 functions operate on the thread holding the lock, and only the synchronization has a lock, so it is used in synchronization; ②wait (), notify (), Notifyall (), They must be used to identify the locks held by the thread they are operating on, because the wait and wake must be threads under the same lock, and the lock can be any object, so these 3 methods are methods in the object class. There is a field flag to determine whether the number of raw products is empty and whether the consumer goods are empty. True indicates that the product has, inform consumer consumption; false is no commodity true: producers wait for consumption, consumer notification, and set to Falsefalse: Consumer waits for production, producer notification, and set to Trueclass resource{private String Name;private int count=1;private boolean flag=false;public synchronized void set (String name) {while (flag) try{ Wait ();} catch (Exception e) {}this.name=name+ "---" +count++; System.out.println (Thread.CurrentThread (). GetName () + "... Producer ... "+this.name); Flag=true;this.notifyall ();} Public synchronized void out () {while (!flag) try{wait ();} catch (Exception e) {}system.out.println (Thread.CurrentThread (). GetName () + "... Consumer ... "+this.name); Flag=false;this.notifyall ();}} public class Producerconsumerdemo{public static void Main (string[] args) {Resource r=new Resource (); Producer pro=new Producer (R); Consumer con=new Consumer (R); Thread T1=new thread (PRO); Thread t2=new thread (con); Thread T3=new thread (PRO); Thread t4=new thread (con); T1.start (); T2.start (); T3.start (); T4.start ();}}

(2), using condition to control thread communication

jdk1.5, a multithreaded upgrade solution is provided: ① replaces the synchronous synchronized with an explicit lock operation; ② replaces Wait (), notify (), Notifyall () in the object class with the condition object, which      can be obtained by lock lock object; ③ a lock object can be bound to multiple condition objects, so that the local thread only wakes the other thread, and before jdk1.5, a synchronization can have only one lock, different synchronizations can only be distinguished by locks, and locks are nested when the deadlock is easy. Class resource{private String name;private int count=1;private Boolean flag=false;private lock lock = new Reentrantlock (); /lock is an interface, and Reentrantlock is a direct subclass of the interface. /private Condition condition_pro=lock.newcondition (); /Create a Condition object representing the producer/private Condition Condition_con=lock.newcondition ();              /using the same lock, create a condition object representing the consumer/public Void set (String name) {lock.lock ();//Lock the code between this statement and Lock.unlock () try{ while (flag) condition_pro.await ();              The producer thread waits for the this.name=name+ "---" On the Conndition_pro object +count++; System.out.println (Thread.CurrentThread (). GetName () + "...              Producer ... "+this.name);               Flag=true;          Condition_con.signalall (); } finally{Lock.unlock ();//unlock () to putIn the finally block.                  }} public void out () {lock.lock ();//Lock the code between this statement and Lock.unlock () try{while (!flag) Condition_con.await (); The consumer thread waits on the Conndition_con object for System.out.println (Thread.CurrentThread (). GetName () + "...          Consumer ... "+this.name);          Flag=false; Condition_pro.signqlall ();          /* Wake up all threads waiting under the Condition_pro object, that is, wake all producer threads */} finally{Lock.unlock ();   }      }  }
  * * (3), using a blocking queue (blockingqueue) to control thread communication * * Blockingqueue is an interface and a sub-interface of the queue. Blockingqueue has a feature: When a producer thread attempts to place an element into the Blockingqueue, the thread is blocked if the queue is full, but the thread is blocked if the queue is empty when the consumer thread tries to remove the element from the Blockingqueue. The two threads of a program can control the communication of threads well by alternately placing elements in blockingqueue and removing elements.                 Blockingqueue provides the following two methods to support blocking: ①put (e): Attempts to place the EU element as blockingqueue, and if the element of the queue is full, the thread is blocked. ②take (): Attempts to remove an element from the Blockingqueue's head, blocking the thread if the element of the queue is empty. Blockingqueue inherits the queue interface, but can also use the methods in the queue interface, which can be grouped into the following three groups: ① inserts elements at the end of the queue, including Add (e), offer (e), put (e) method, when                 When the queue is full, these three methods throw an exception, return false, and block the queue, respectively. ② deletes and returns the deleted element at the head of the queue.                 Including the Remove (), poll (), and take () methods, when the queue is empty, these three methods throw exceptions, return false, and block the queue. ③ removes the element at the head of the queue without deleting it. The element () and peek () methods are included, and when the queue is empty, the two methods throw an exception and return false, respectively. 
public class blockingqueuetest{public static void Main (string[] args) throws exception{//    Create a blockingqueueblockingqueue<string> b=new arrayblockingqueue<> (1) with a capacity of 1;    Start 3 producer Threads new Producer (b). Start ();    New Producer (b). Start ();    New Producer (b). Start (); Start a consumer thread new Consumer (b). Start ();}} Class Producer extends thread{private blockingqueue<string> b;public Producer (blockingqueue<string> b) {th Is.b=b;}    Public synchronized void Run () {String [] str=new string[]{"java", "struts", "Spring"}; for (int i=0;i<9999999;i++) {System.out.println (GetName () + "producers prepare to produce collection elements!        ");            try{b.put (str[i%3]);            Sleep (1000);        Try putting the element in, if the queue is full, then the thread is blocked}catch (Exception e) {System.out.println (e);}    System.out.println (GetName () + "production Complete:" +b); }}} class Consumer extends thread{private blockingqueue<string> b; public Consumer (blockingqueue<string> b) {this.b=b;} Public synchronized void Run () {while (true) {System.out.println (GetName () + "consumer ready to consume collection elements!        ");            Try{Sleep (1000);        An attempt was made to remove the element, and if the queue is empty, the thread is blocked B.take ();        }catch (Exception e) {System.out.println (e);}    System.out.println (GetName () + "consumption completed:" +b); }}

7. Thread Pool

 Core of the thread pool: ①. Create a bunch of threads to put in memory and spare. The Run method for each thread does not end.      In the absence of a task, the wait state.        ② If a compute task arrives, it gets a thread object from the thread pool and sets the task to the thread object.      After Setup is complete, send notify to notify the thread to perform the task. When the ③ task executes, it puts the thread back into the thread pool and enters the wait state. The rational use of the thread pool can bring three benefits. Reduce resource consumption. Reduce the consumption caused by thread creation and destruction by reusing the threads that have been created. Improve response speed. When a task arrives, the task can be executed immediately without waiting for the thread to be created. Improve the manageability of threads. Threads are scarce resources that, if created indefinitely, not only consume system resources, but also reduce system stability, using a thread pool for uniform allocation, tuning, and monitoring. Using the Executors factory class to generate the thread pool the greatest advantage of the executor thread pool framework is to decouple the commit and execution of the task. The task that the client will perform is encapsulated into a task and then committed to Executorservice (implementing Class Threadpoolexecutor, Scheduledthreadpoolexecutor) inherits the Executor interface (note the executor interface and executors factory Class), and the steps to perform multithreaded tasks using executors are as follows:? Call the static factory method of the executors class to create a Executorservice object that represents a thread pool; Create an instance of the Runnable implementation class or callable implementation class as a thread execution task;? Call the Submit () method of the Executorservice object to submit the Runnable instance or callable instance; When you do not want to commit the task, call the shutdown () method of the Executorservice object to close the thread pool.    The "Focus" threadpoolexecutor a simple thread pool, which is the creation of threads to spare.    Create 3 runnable objects, which will take 3 seconds to execute in each of these objects.    3 tasks are submitted to the thread pool, but the thread pool size is 1, which means that at most one task is executed at the same time. Executorservice pool = executors.newfixedthreadpool (size);    Scheduledthreadpoolexecutor can be scheduled to the thread pool, the task can be in accordance with a certain rules of the cycle, repeated execution. TimingTasks, typically using Spring-timer instead, support more complex task scheduling methods.    Scheduledexecutorservice pool = executors.newscheduledthreadpool (size);            Timed Recurring Call Method: Scheduleatfixedrate: Performs the task at a fixed frequency and calculates the frequency as the start time of the task.            Assume that the interval is 2 seconds, and it takes 3 seconds for each task to execute.            The frequency interval is smaller than the time required for the task.            When the previous task is complete, the next task is executed immediately. * Interval is calculated from the start time Schedulewithfixeddelay: Perform tasks at regular intervals

8. Deadlock

产生死锁的四个必要条件如下。当下边的四个条件都满足时即产生死锁,即任意一个条件不满足既不会产生死锁。(1)死锁的四个必要条件 互斥条件:资源不能被共享,只能被同一个进程使用 请求与保持条件:已经得到资源的进程可以申请新的资源 非剥夺条件:已经分配的资源不能从相应的进程中被强制剥夺 循环等待条件:系统中若干进程组成环路,该环路中每个进程都在等待相邻进程占用的资源举个常见的死锁例子:进程A中包含资源A,进程B中包含资源B,A的下一步需要资源B,B的下一步需要资源A,所以它们就互相等待对方占有的资源释放,所以也就产生了一个循环等待死锁。(2)处理死锁的方法忽略该问题,也即鸵鸟算法。当发生了什么问题时,不管他,直接跳过,无视它;检测死锁并恢复;资源进行动态分配;破除上面的四种死锁条件之一。

9. Thread-related classes

ThreadLocal

Threadlocal It is not a thread, but a data storage class that can store data in each thread, through which it can store data in the specified thread, and after the data is stored, only the stored data can be obtained in the specified thread, and the data for that thread cannot be obtained for other threads. That is, multiple threads obtained by the same threadlocal is not the same thing, even if sometimes the result is the same (contingency, two lines thread two copies of the same thing), but they acquire the essence is different. The use of this tool class simplifies concurrent access to multithreaded programming, and it provides a simple means of isolating competing resources for multi-threaded programs.

For the problem of multi-thread resource sharing, the synchronization mechanism adopts the way of "time-changing Space", and threadlocal adopts "space-changing Time". The former provides only one copy of the variable, allowing different threads to queue access, and the latter provides a variable for each thread, so it can be accessed at the same time without affecting each other.
If you need to share resources between multiple threads to achieve inter-thread communication, use the synchronization mechanism, or you can use threadlocal if you only need to isolate the relational resources between multithreading.

7 Multi-Threading

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.