Home  >  Article  >  Java  >  Four ways to implement multithreading in Java

Four ways to implement multithreading in Java

WBOY
WBOYforward
2022-07-04 13:56:282354browse

This article brings you relevant knowledge about java, which mainly sorts out the issues related to the four ways to implement multi-threading, including inheriting the Thread class and implementing the Callable interface through the FutureTask wrapper To create Thread threads, use ExecutorService, Callable, Future to implement multi-threading with returned results, etc. Let's take a look at it, I hope it will be helpful to everyone.

Four ways to implement multithreading in Java

Recommended study: "java video tutorial"

JavaMulti-threading implementation methodThere are four main types:

  • Inherit the Thread class and implement the Runnable interface

  • Implement the Callable interface to create Thread threads through the FutureTask wrapper

  • Use ExecutorService and Callable

  • Future to implement multi-threading with returned results

The first two The first two methods have no return value after the thread is executed, and the latter two have return values.

1. Four ways to implement multi-threading

1. Inherit the Thread class to create threads

The Thread class is essentially an instance that implements the Runnable interface and represents a thread. Example. The only way to start a thread is through the start() instance method of the Thread class. The start() method is a native method that will start a new thread and execute the run() method. It is very simple to implement multi-threading in this way. By directly extending Thread through your own class and overriding the run() method, you can start a new thread and execute your own defined run() method. For example:

public class MyThread extends Thread {  
  public void run() {  
   System.out.println("MyThread.run()");  
  }  
}  

MyThread myThread1 = new MyThread();  
MyThread myThread2 = new MyThread();  
myThread1.start();  
myThread2.start();

2. Implement the Runnable interface to create a thread

If your class has extended another class, you cannot directly extend Thread. At this time, you can implement a Runnable interface, as follows:

public class MyThread extends OtherClass implements Runnable {  
  public void run() {  
   System.out.println("MyThread.run()");  
  }  
}

In order to start MyThread, you need to instantiate a Thread first and pass in your own MyThread instance:

MyThread myThread = new MyThread();  
Thread thread = new Thread(myThread);  
thread.start();

In fact, when a Runnable target parameter is passed to Thread, Thread's run( ) method will call target.run(), refer to the JDK source code:

public void run() {  
  if (target != null) {  
   target.run();  
  }  
}

3. Implement the Callable interface to create a Thread thread through the FutureTask wrapper

Callable interface (there is only one method) The definition is as follows:

public interface Callable<v>   { 
  V call() throws Exception;   } 

public class SomeCallable<v> extends OtherClass implements Callable<v> {

    @Override
    public V call() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

}</v></v></v>
Callable<v> oneCallable = new SomeCallable<v>();   
//由Callable<integer>创建一个FutureTask<integer>对象:   
FutureTask<v> oneTask = new FutureTask<v>(oneCallable);   
//注释:FutureTask<integer>是一个包装器,它通过接受Callable<integer>来创建,它同时实现了Future和Runnable接口。 
  //由FutureTask<integer>创建一个Thread对象:   
Thread oneThread = new Thread(oneTask);   
oneThread.start();   //至此,一个线程就创建完成了。</integer></integer></integer></v></v></integer></integer></v></v>

4. Use ExecutorService, Callable, and Future to implement threads that return results.

The three interfaces of ExecutorService, Callable, and Future actually belong to the Executor framework. The thread that returns the result is a new feature introduced in JDK1.5. With this feature, you no longer need to go through a lot of trouble to get the return value. And even if you implement it yourself, it may be full of loopholes.

Tasks that can return values ​​must implement the Callable interface. Similarly, tasks that do not return a value must implement the Runnable interface.

After executing the Callable task, you can obtain a Future object. By calling get on the object, you can obtain the Object returned by the Callable task.

Note: The get method is blocking, that is: the thread returns no result, and the get method will wait forever.

Combined with the thread pool interface ExecutorService, the legendary multi-threading with returned results can be realized.

The following provides a complete multi-threaded test example with returned results. It has been verified under JDK1.5 and can be used directly. The code is as follows:

import java.util.concurrent.*;  
import java.util.Date;  
import java.util.List;  
import java.util.ArrayList;  

/** 
* 有返回值的线程 
*/  
@SuppressWarnings("unchecked")  
public class Test {  
public static void main(String[] args) throws ExecutionException,  
    InterruptedException {  
   System.out.println("----程序开始运行----");  
   Date date1 = new Date();  

   int taskSize = 5;  
   // 创建一个线程池  
   ExecutorService pool = Executors.newFixedThreadPool(taskSize);  
   // 创建多个有返回值的任务  
   List<future> list = new ArrayList<future>();  
   for (int i = 0; i >>" + f.get().toString());  
    list.add(f);  
   }  
   // 关闭线程池  
   pool.shutdown();  

   // 获取所有并发任务的运行结果  
   for (Future f : list) {  
    // 从Future对象上获取任务的返回值,并输出到控制台  
    System.out.println(">>>" + f.get().toString());  
   }  

   Date date2 = new Date();  
   System.out.println("----程序结束运行----,程序运行时间【"  
     + (date2.getTime() - date1.getTime()) + "毫秒】");  
}  
}  

class MyCallable implements Callable<object> {  
private String taskNum;  

MyCallable(String taskNum) {  
   this.taskNum = taskNum;  
}  

public Object call() throws Exception {  
   System.out.println(">>>" + taskNum + "任务启动");  
   Date dateTmp1 = new Date();  
   Thread.sleep(1000);  
   Date dateTmp2 = new Date();  
   long time = dateTmp2.getTime() - dateTmp1.getTime();  
   System.out.println(">>>" + taskNum + "任务终止");  
   return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";  
}  
}</object></future></future>

2. Multi-threading related knowledge

1. What is the difference between Runnable and Callable?

· The main difference is that the run method of the Runnable interface has no return value;

· The call method of the Callable interface has a return value and supports generics The run method of the Runnable interface can only throw runtime exceptions and cannot capture and handle them;

· The call method of the Callable interface allows throwing exceptions and can obtain exception information

2. How to start a new thread and what is the difference between calling the start and run methods?

· The thread object calls the run method without starting the thread. Only object calls methods.

· The thread object calls start to open the thread, and lets the jvm call the run method to execute in the opened thread. Calling the start method can start the thread and make the thread enter the ready state, and the run method just A common method of thread is still executed in the main thread.

3. Basic thread-related methods?

The basic methods related to threads include wait, notify, notifyAll, sleep, join, yield, etc.

· Thread wait (wait) The thread that calls this method Entering the waiting state, it will only return if it waits for notification from another thread or is interrupted. It should be noted that after calling the wait() method, the object's lock will be released. Therefore, the wait method is generally used in synchronized methods or synchronized code blocks.

· Thread sleep (sleep) sleep causes the current thread to sleep. Unlike the wait method, sleep will not release the currently occupied lock. sleep(long) will cause the thread to enter TIMED-WATING. state, and the wait() method will cause the current thread to enter the WATING state.

· Thread yield (yield) yield will cause the current thread to give up the CPU execution time slice and compete with other threads for the CPU time slice again. Generally speaking, threads with high priority have a greater chance of successfully competing for CPU time slices, but this is not absolute. Some operating systems are not sensitive to thread priority.

· Thread interrupt (interrupt) Interrupting a thread is intended to give the thread a notification signal, which will affect an interrupt flag inside the thread. This thread itself will not change the state (such as blocking, termination, etc.) because of this

· Join waits for other threads to terminate the join() method, waits for other threads to terminate, and calls it in the current thread The join() method of a thread will turn the current thread into a blocked state and return to another thread to end. The current thread will then change from a blocked state to a ready state, waiting for the favor of the CPU.

· Thread wake-up (notify) The notify() method in the Object class wakes up a single thread waiting on this object monitor. If all threads are waiting on this object, one of the threads will be chosen to wake up. The choice is arbitrary. , and occurs when an implementation decision is made, the thread waits on the object's monitor by calling one of the wait() methods. The awakened thread cannot continue execution until the current thread relinquishes the lock on this object. 's threads will compete in the normal manner with all other threads actively synchronizing on the object. A similar method is notifyAll(), which wakes up all threads waiting on the monitor again.

5. What is the difference between wait() and sleep()?

· ① From different classes wait(): from Object class; sleep(): from Thread class;

· ② Regarding the release of locks: wait(): The lock will be released during the waiting process; sleep(): The lock will not be released during the waiting process

· ③ Scope of use: wait(): must be used in a synchronized code block; sleep(): can be used anywhere;

· ④ Whether to catch exceptions wait(): No need to catch exceptions; sleep (): Need to catch exceptions;

6. Multi-threading principle

Multi-threading principle:Multi-threading is done through concurrency. For a CPU, it can only execute one program at a certain point in time, that is, it can only run one process at the same time. The CPU will continuously switch between these processes, and each thread will execute for one time. Because the execution speed of the CPU is too fast relative to our perception, although the CPU rotates execution between multiple processes, we feel as if multiple processes are executing at the same time.

The CPU will switch between multiple processes. If we open too many programs, the time it takes for the CPU to switch to each process will also become longer, and we will also feel that the machine is running slower. Therefore, the reasonable use of multi-threading can improve efficiency, but extensive use does not bring us an improvement in efficiency.

Multi-threading technology mainly solves the problem of multiple thread execution in the processor unit. It can significantly reduce the idle time of the processor unit and increase the throughput capacity of the processor unit.

Four ways to implement multithreading in Java

Recommended study: "java video tutorial"

The above is the detailed content of Four ways to implement multithreading in Java. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete