Java multi-threaded programming - based learning

1. Basic Concepts

Next we start to understand what is the process and thread? What is the relationship between them is?

  • Process : The process is running instance of a program (for example: a running Eclipse is a process), the process is the application program to the operating system, the basic unit of resources (such as memory and file handles) are.
  • Thread : A thread is the smallest unit of an operating system capable of operation scheduling.
  • Relationship : A process can contain multiple threads, threads share the process of change in the resource the same process for all, such as memory space, file handles and so on.

The advantages of using multiple threads:

  • In our multi-core system, you can take advantage of to improve CPU utilization.
  • Improve the throughput of the system, when a thread because I / O operation and is waiting for other threads can still perform its operations.
  • More responsive, for the Web application, a request that is slow and does not affect the operation of other requests.

2. Thread creation and start

There are two ways to create threads:

  • Thread class inheritance
  • Implement Runnable
Thread class inheritance

The following code is to define a subclass of Thread class way to create and start the thread:

public class CreateThreadDemo {
    public static void main(String[] args) {
        //创建线程
        MyThread myThread = new MyThread();
        //启动线程
        myThread.start();
    }
}

// 定义Thread类的子类
class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("myThread begin running, threadName:" + Thread.currentThread().getName());
    }
}
Implement Runnable

The following code is a way to achieve Runnable interface to create and start the thread:

public class CreateThreadByRunnable {
    public static void main(String[] args) {
        //创建线程
        Thread myThread = new Thread(new MyTask());
        //启动线程
        myThread.start();
    }
}

// 实现Runnable接口
class MyTask implements Runnable{
    @Override
    public void run() {
        System.out.println("myThread begin running, threadName:" + Thread.currentThread().getName());
    }
}

3. The common method

The following table lists some of the common methods thread:

method Features Remark
currentThread Returns the current thread of execution of code The same piece of code () call to Thread.currentThread, the return value may correspond to a different thread
yield The current thread to give up its occupation of treatment, may result in the current thread is suspended This method is not reliable, it is called the current thread may still continue to run
sleep The current thread to sleep a specified time
start Start the corresponding thread start a Thread instance method can only be called once, multiple calls can result in an exception is thrown
run For task processing logic to implement threads Called directly by the Java virtual machine, the application should not call general
interrupt Interrupt thread The thread's interrupt flag is set to false
interrupted Determine whether the current thread is interrupted in the state, and clears the thread's interrupt status
isInterrupted Determine whether the calling thread into a break Thread through this method in response to interrupts
getName Get the name of the thread
join Waiting for the end of the corresponding thread running If thread A thread B calls the method, then run thread A will be suspended, know that the end of the thread B runs
getId Gets the thread identifier

4. Thread Life Cycle

A thread created from start to the end of its run throughout the life cycle may go through several states, as shown below:
Here Insert Picture Description

  • NEW : that has been created (the calling thread start method) not started a thread in this state, since a thread can only start once all possible only once in this state.
  • RUNNABLE : This state can be regarded as a composite state, comprising two sub-states, and RUNNING REAY. READY represents scheduling may be a thread scheduler to enter the RUNNING state. A thread may be changed in the RUNNING state READY status to Thread.yield () method.
  • BLOCKED : When one thread initiate a blocking IO operation, or apply for exclusive resources, not acquired lock, enters the blocking BLOCKED state. After blocking IO operation is complete or to acquire a lock, then the state to RUNNABLE.
  • WAITING : When a thread executes Object.wait () or LockSupport.part (Object) method, it will go WAITING state. This state must be awakened by another thread calls Object.notify () / LockSupport.unpart (Object) method, thus again converted RUNNABLE state.
  • TIMED_WAITING : When a thread calls Thread.sleep (long), Object.wait (long ), after LockSupport.parkNanos (long) and other methods, will enter a waiting state with a time limit of TIMED_WAITING, when the waiting time to meet, will automatically converted RUNNABLE state.
  • TERMINATED: end of the thread has been performed in TERMINATED state. Since a thread can only start once all possible only once in this state.

5. Thread break

What is interrupted

Off can be seen as an indication sent by a thread (initiating thread) to another thread (target thread), the indication is used to indicate the target thread to initiate thread wishes to stop its operation being performed.
Interrupted only appeal launched on behalf of a thread, and this demand can be met depends on the target thread itself, could meet the demands of the target thread thread is initiated, it may simply ignore the demands initiated by the thread.

Instructions

Look at the following code:

public class ThreadInterrupt {
    public static void main(String[] args) {
        // 创建子线程
        Thread myThread = new Thread(new InterruptTask());
        // 启动子线程
        myThread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 中断子线程
        myThread.interrupt();

    }
}

// 实现Runnable接口
class InterruptTask implements Runnable{
    @Override
    public void run() {
        // while条件是检测当前线程是否被中断
        while(!Thread.currentThread().isInterrupted()){
            System.out.println("thread is running...");
        }
    }
}
  • The main thread of the child thread by calling interrupt () method, the child thread interrupt flag is set to true.
  • Acquiring own child thread interrupt flag value by calling Thread.currentThread (). IsInterrupted (), if it is detected is interrupted, the response may be unprocessed.
Interrupt response

Many Java standard library method for blocking responds to interrupts are thrown InterruptedException exception.
We need to note that after an exception is thrown, the interrupt flag is cleared (interrupts the thread flag is reset from true to false). We look at the following example:

public class ThreadInterrupt {
    public static void main(String[] args) {
        // 创建子线程
        Thread myThread = new Thread(new InterruptTask());
        // 启动子线程
        myThread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 中断子线程
        myThread.interrupt();

    }
}

// 实现Runnable接口
class InterruptTask implements Runnable{
    @Override
    public void run() {
        try {
            // 子线程挂起3秒
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        	System.out.println("子线程中断标记:" + Thread.currentThread().isInterrupted());
            e.printStackTrace();
        }
    }
}

After the result of the program:

子线程中断标记:false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.demo.InterruptTask.run(ThreadInterrupt.java:26)
	at java.lang.Thread.run(Thread.java:745)

We see the child thread is interrupted in the main thread hangs in the process, thrown InterruptedException exception and interrupt flag is reset to false.
Since the interrupt flag is reset, and if we are not handled properly, may cause some problems, look at the following example:

public class ThreadInterrupt {
    public static void main(String[] args) {
        // 创建子线程
        Thread myThread = new Thread(new InterruptTask());
        // 启动子线程
        myThread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 中断子线程
        myThread.interrupt();

    }
}

// 实现Runnable接口
class InterruptTask implements Runnable{
    @Override
    public void run() {
        // 业务方法挂起期间被中断
        service();
        if(Thread.currentThread().isInterrupted()){
            System.out.println("子线程被中断了");
        }else{
            System.out.println("子线程未被中断");
        }
    }

    // 子线程执行的业务方法
    public void service(){
        try {
            // 这边模拟子线程在执行的过程中挂起
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
            // 这边捕获到异常什么也不做
        }
    }
}

The above example demonstrates, when we capture InterruptedException anomaly (interruption flag is reset to false), we did not do anything here, leading to the caller can not determine the correct interrupt flag, resulting in faulty logic. We can deal with by the following method:

	// 子线程执行的业务方法
    public void service(){
        try {
            // 这边模拟子线程在执行的过程中挂起
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
            // 保留线程中断标记
            Thread.currentThread().interrupt();
        }
    }

After the capture InterruptedException exception by calling Thread.currentThread (). Interrupt () method preserves the interrupt flag, so that the caller can know the current thread it is interrupted.

6. Wait (wait) / notification (Notify)

In Java, Object.wait and Object.nofity be used to implement and notifications. Object.wait role is to execute the thread is suspended (lifecycle state to WAITING), which can be used to achieve wait; Object.notify role is to wake up a thread to be suspended, call the method can be realized notice. We look to use:

public class ThreadWaitNofity {
    public static void main(String[] args) {
        Object o = new Object();
        // 新建一个等待线程
        Thread waitThread = new Thread(() -> {
            // 注意:Object.wait方法只能在synchronized块中执行
            synchronized (o){
                try {
                    System.out.println("线程进入了等待,开始等待时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                    o.wait();
                    System.out.println("线程被唤醒了,被唤醒时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    // 恢复线程中断标记
                    Thread.currentThread().interrupt();
                }
            }
        });

        // 新建一个通知线程
        Thread notifyThread = new Thread(() -> {
            try {
                // 延迟3秒钟
                Thread.sleep(3000);
                // 注意:Object.notify方法只能在synchronized块中执行
                synchronized (o){
                    o.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 启动等待线程
        waitThread.start();
        // 启动唤醒线程
        notifyThread.start();
    }
}

Results are as follows:

线程进入了等待,开始等待时间:2020-03-11 14:49:14
线程被唤醒了,被唤醒时间:2020-03-11 14:49:17

About the difference between sleep and wait method method is often asked in the interview, we summarized as follows:

wait sleep
Limitations The method can be called only wait in synchronization synchronized in No need to call in the synchronization
Role of the object wait method defined in the Object class, acting on the object itself sleep method defined in the Thread, the role of the current thread
Release lock resources Release the lock Do not release locks
Wake conditions Other thread calls the object's notify () or notifyAll () method Timeout or interrupt
Methods Properties Examples of the method is the wait sleep is a static method
Released seven original articles · won praise 3 · Views 2101

Guess you like

Origin blog.csdn.net/ym572170/article/details/104790598