Do you know Java multithreading? (a) Java multithreading skills

Source: Internet
Author: User
Tags deprecated thread class thread stop throw exception

1. Processes and Threads

A program is a process, and multiple tasks in a program are called threads.

Process is the basic unit of resource allocation and the basic unit of dispatching operation.

A thread is the smallest unit of execution in a process, that is, the basic unit of the execution processor dispatch.

As an example:

Open the Task Manager on your computer, it will show all the processes of the current machine, qq,360, etc., when QQ is running, there are many subtasks running at the same time. For example, when you type and send emoticons, the different functions can be run at the same time as a friend video, and each of these tasks can be understood as "threads" at work.

2. Use multithreading

In Java's JDK development package, the support for multithreaded technology has been brought in, making it easy to do multithreaded programming. There are two ways to implement multithreaded programming, one is to inherit the Thread class, and the other is to implement the Runnable interface. Using the inherited thread class to create threads, the biggest limitation is not to inherit more, so in order to support multiple inheritance, it is possible to implement the Runnable interface in a way. It should be stated that both of these approaches are of the same nature at work and have no essential difference. As shown below:

1. Inheriting the Thread class

public class MyThread extends Thread {    @Override    public void run() {        //...    }        public static void main(String[] args) {        MyThread thread = new MyThread();        thread.start();    }}

2. Implement the Runnable interface

 public static void main(String[] args) throws InterruptedException {     new Thread(new Runnable() {         @Override         public void run() {             //...         }     }).start(); }

The start () method in the Thread.java class notifies the thread planner that this thread is ready to wait for the run () method of the calling thread object. This process actually allows the system to schedule a time to invoke the run () method in thread, which is to make the thread run, the multithreading is asynchronous, and the thread is started in the code in the order not the thread is called.

Thread Construction method
Thread()
Assigns a new Thread object.
Thread(Runnable target)
Assigns a new Thread object.
Thread(Runnable target, String name)
Assigns a new Thread object.
Thread(String name)
Assigns a new Thread object.
Thread(ThreadGroup group, Runnable target)
Assigns a new Thread object.
Thread(ThreadGroup group, Runnable target, String name)
Assigns a new Thread object so that target it will run as its object, assign the specified name as its name, and act as group a member of the referenced thread group.
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
Assigns a new Thread object so that target it will run as its name name, as a member of the group referenced thread group, and with the specified stack size .
Thread(ThreadGroup group, String name)
Assigns a new Thread object.
3. Instance variables and thread safety

Instance variables in a custom thread class can have shared and unshared points for other threads. When each thread has its own instance variable, the variable is not shared. Sharing data is where multiple threads can access the same variable. Consider the following example:

public class MyThread implements Runnable {    private int count = 5;    @Override    public void run() {        count--;        System.out.println("线程"+Thread.currentThread().getName()+" 计算 count = "+count);    }}

The above code defines a thread class that implements the effect of the count variable minus one. Run the class Runjava code as follows:

public class Ruu {    public static void main(String[] args) throws InterruptedException {        MyThread myThread = new MyThread();        Thread a = new Thread(myThread,"A");        Thread b = new Thread(myThread,"B");        Thread c = new Thread(myThread,"C");        Thread d = new Thread(myThread,"D");        Thread e = new Thread(myThread,"E");        a.start();        b.start();        c.start();        d.start();        e.start();    }}

The printing results are as follows:

 线程C 计算 count = 3 线程B 计算 count = 3 线程A 计算 count = 2 线程D 计算 count = 1 线程E 计算 count = 0

Thread C,b Print results are all 3, indicating that both C and B handle count at the same time, resulting in a "non-threading security issue." And we want to get the print results are not repeated, but in turn descending.

In some JVMs, the operation of i--is divided into the following 3 steps:

    1. Gets the value of the original variable.
    2. Calculates the i-1.
    3. Assigns a value to I.

In these three steps, a non-threading security issue is bound to occur if more than one thread is accessing it at the same time.

The workaround is to use the Synchronized Sync keyword to queue each thread to execute the run () method. The modified run () method:

public class MyThread implements Runnable {    private int count = 5;    @Override    synchronized public void run() {        count--;        System.out.println("线程"+Thread.currentThread().getName()+" 计算 count = "+count);    }}

Printing results:

线程B 计算 count = 4线程C 计算 count = 3线程A 计算 count = 2线程E 计算 count = 1线程D 计算 count = 0
About the System.out.println () method

First look at the System.out.println () method source code:

    public void println(String x) {        synchronized (this) {            print(x);            newLine();        }    }

Although the Synchronized keyword is used internally by the println () method, the code shown below is still subject to non-thread safety issues when it executes.

System.out.println("线程"+Thread.currentThread().getName()+" 计算 count = "+count--);

The reason is that the println () method is internally synchronized, but the i--operation occurs before entering println (), so there is a probability of a non-threading security problem.

4, multithreading Method 1. CurrentThread () method

The CurrentThread () method returns information about which thread the code snippet is being called from.

Thread.currentThread().getName()
2. IsAlive () method

The function of method IsAlive () is to determine whether the current thread is active.

thread.isAlive();
3. Sleep () method

The function of the sleep () method is to have the current "executing thread" hibernate (paused) within the specified number of milliseconds. This "executing thread" refers to the thread returned by This.currentthread ().

Thread.sleep()
4. GetId () method

The function of the GetId () method is to obtain a unique identifier for the thread.

thread.getId()
5. Stop thread

Stopping a thread is a technical point that is important in multithreaded development. Stopping a thread is not as straightforward as a break statement, and requires some tricky processing.

There are 3 ways to terminate a running thread in Java:

1) Use the exit flag to cause the thread to exit normally, that is, when the run () method finishes, the thread stops.

2) Use the Stop () method to forcibly terminate a thread, but this method is deprecated because the method is obsolete and may produce unpredictable results after use.

3) Use the interrupt () method to break the thread.

1. Violent law Stop thread

A Java.lang.ThreadDeath exception is thrown when the stop () method is called, but in the usual case, this exception does not require a display to be snapped.

        try {            myThread.stop();        } catch (ThreadDeath e) {            e.printStackTrace();        }

The method Stop () has been invalidated because it is possible to make some cleanup work impossible if the thread is forced to stop the thread. Another situation is that the locked object is "unlocked", resulting in data not synchronized processing, the occurrence of inconsistent data. Examples are as follows:

public class Userpass {private String username = "AA";    Private String Password = "AA";    Public String GetUserName () {return username;    } public void Setusername (String username) {this.username = username;    } public String GetPassword () {return password;    } public void SetPassword (String password) {this.password = password;        } synchronized public void println (string username, string password) {this.username = username;        try {thread.sleep (1000);        } catch (Interruptedexception e) {e.printstacktrace ();    } this.password = password;        public static void Main (string[] args) throws Interruptedexception {Userpass userpass = new Userpass (); Thread thread = new Thread (new Runnable () {@Override public void run () {Userpass            . println ("BB", "BB");        }        });        Thread.Start ();        Thread.Sleep (500); ThrEad.stop ();    System.out.println (Userpass.getusername () + "" +userpass.getpassword ()); }}

Operation Result:

bb AA
2. Exception method Stop thread

Using the interrupt () method does not really stop the thread, the call to the interrupt () method simply hits a stop mark in the current thread and does not really stop the thread.

So how can we tell if the thread has been tagged with a stop tag, the thread class provides two methods.

interrupted() 测试当前线程是否已经中断。isInterrupted() 测试线程是否已经中断。

The interrupted () method not only determines whether the current thread has been interrupted, but also clears the interrupt state of the thread. For the isinterrupted () method, only the current thread is determined to be interrupted, and the interrupt state of the thread is not cleared.

Only the above two methods can be controlled by the while(!this.isInterrupted()){} code, but if there are other statements outside the loop, the program will continue to run. You can then throw an exception so that the thread stops completely. Examples are as follows:

public class MyThread extends Thread {    @Override    public void run() {        try {            for (int i=0; i<50000; i++){                if (this.isInterrupted()) {                    System.out.println("已经是停止状态了!");                    throw new InterruptedException();                }                System.out.println(i);            }            System.out.println("不抛出异常,我会被执行的哦!");        } catch (Exception e) {//            e.printStackTrace();        }    }        public static void main(String[] args) throws InterruptedException {        MyThread myThread =new MyThread();        myThread.start();        Thread.sleep(100);        myThread.interrupt();    }    }

Printing results:

...2490249124922493已经是停止状态了!
Attention

If the thread is stopped in the sleep () state, that is, the thread object's run () method contains the sleep () method, and the method is executed during this time, an thread.interrupt() exception is thrown java.lang.InterruptedException: sleep interrupted that indicates that sleep is interrupted.

3.return Stop Thread

The return method is very simple, just need to change the exception method throws the exception to return. The code is as follows:

public class MyThread extends Thread {    @Override    public void run() {                for (int i=0; i<50000; i++){            if (this.isInterrupted()) {                System.out.println("已经是停止状态了!");                return;//替换此处            }            System.out.println(i);        }        System.out.println("不进行return,我会被执行的哦!");           }}

However, it is recommended to use "throw exception" to achieve the thread stop, because the exception information in the catch block can be related to the processing, and the use of exceptions can be better, more convenient control procedures to run the process, not in the code to appear multiple return, causing pollution.

6. Suspend thread

Pausing a thread means that the thread can also resume running. In Java Multi-threading, you can use the Suspend () method to pause a thread and resume the execution of a thread using the resume () method.

Both methods have been deprecated as stop (), because if used improperly, it is very easy to monopolize the public synchronization object so that other threads cannot access the public synchronization object. Examples are as follows:

public class MyThread extends Thread {    private Integer i = 0;    @Override    public void run() {        while (true) {            i++;            System.out.println(i);        }    }    public Integer getI() {        return i;    }        public static void main(String[] args) throws InterruptedException {        MyThread myThread =new MyThread();        myThread.start();        Thread.sleep(100);        myThread.suspend();        System.out.println("main end");    }    }

Printing results:

...3398339934003401

Executing the previous program will never print the main end. This occurs because the PrintStream object synchronization lock is not released when the program runs inside the println () method when it is stopped. Method println () source code is as follows:

    public void println(String x) {        synchronized (this) {            print(x);            newLine();        }    }

This causes the println () method of the current PrintStream object to remain in a "paused" state, and the lock is not freed by the mythread thread, and the Code System.out.println ("main End") in the main () method is still waiting in a silly line, Cause a delay in running the print.

It is also easy to use the suspend () and resume () methods to prevent data from being synchronized due to thread pauses, as shown in the following example:

  public class UserPass2 {private String username = "AA";    Private String Password = "AA";    Public String GetUserName () {return username;    } public String GetPassword () {return password;        The public void SetValue (string username, string password) {this.username = username;        if (Thread.CurrentThread (). GetName (). Equals ("a")) {Thread.CurrentThread (). suspend ();    } this.password = password;        public static void Main (string[] args) throws Interruptedexception {UserPass2 userpass = new UserPass2 (); New Thread (New Runnable () {@Override public void run () {userpass.setvalue ("BB")            , "BB");        }}, "a"). Start (); New Thread (New Runnable () {@Override public void run () {System.out.println (userpass            . GetUserName () + "" +userpass.getpassword ());    }}, "B"). Start (); }}

Printing results:

bb AA
7. Yield () method

The yield () method is used to discard the current CPU resources and give it to other tasks to occupy CPU execution time. But the time to give up is uncertain, it is possible to just give up, and immediately get the CPU time slice.

public static void yield()  
8. Priority of Threads

In the operating system, threads can prioritize, and higher-priority threads get more CPU resources, which is the task in which the CPU prioritizes higher-priority thread objects.

Setting the thread priority helps the thread planner determine which thread will be selected for priority execution next time.

Set thread priority using the SetPriority () method, the JDK source code for this method is as follows:

    public final void setPriority(int newPriority) {        ThreadGroup g;        checkAccess();        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {            throw new IllegalArgumentException();        }        if((g = getThreadGroup()) != null) {            if (newPriority > g.getMaxPriority()) {                newPriority = g.getMaxPriority();            }            setPriority0(priority = newPriority);        }    }

In Java, thread precedence is divided into 10 levels of 1 to 10, and if less than 1 or greater than 10, the JDK throws an exception.

The 3 priority constants defined from the JDK indicate that the thread priority defaults to 5.

    public final static int MIN_PRIORITY = 1;    public final static int NORM_PRIORITY = 5;    public final static int MAX_PRIORITY = 10;

Thread precedence is inherited, such as a thread that initiates a B thread, and the B thread has the same priority as a.

Thread precedence is rule-independent, regardless of the order in which the start () method is executed in code, and the priority size.

The thread priority is random, and the CPU tries to make the thread priority higher first, but not absolutely. That is, a higher thread priority does not have to be performed before the thread has a lower priority.

9. Daemon Thread

There are two kinds of threads in Java, one is the user thread, and the other is a daemon thread.

What is a daemon thread? A daemon thread is a special thread that is automatically destroyed by a daemon thread when there is no non-daemon thread in the process. A typical daemon thread is a garbage collection thread, and when there is no non-daemon thread in the process, the garbage collection thread will not have the necessary, automatic destruction. It can simply be said that any one daemon thread is a non-daemon nanny.

How do I set the daemon thread? Set to the user thread by Thread.setdaemon (false), set to the daemon thread by Thread.setdaemon (true). If you do not set a property, the default is the user thread.

thread.setDaemon(true);

Examples are as follows:

public class MyThread extends Thread {    private int i = 0;    @Override    public void run() {        try {            while (true){                i++;                System.out.println("i="+i);                Thread.sleep(1000);            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }        public static void main(String[] args) throws InterruptedException {        MyThread thread = new MyThread();        thread.setDaemon(true);        thread.start();        Thread.sleep(5000);        System.out.println("我离开后thread对象也就不再打印了");    }}

Printing results:

i=1i=2i=3i=4i=5我离开后thread对象也就不再打印了
References and summaries

The core technology of Java multithreaded programming Gaohong

This article mainly introduces the thread class API, is to learn multi-threaded deeper knowledge lay some foundation, the article if there are errors please correct in the comments.

Do you know Java multithreading? (a) Java multithreading skills

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.