Home  >  Article  >  Java  >  How to implement multithreading in Java? (code example)

How to implement multithreading in Java? (code example)

青灯夜游
青灯夜游forward
2019-02-26 16:47:164829browse

What this article brings to you is how to implement multi-threading in Java? (Code sample) has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Method 1: Inherit the class and override the method run()

We override run() in the subclass of the created Thread class , just add the code to be executed by the thread.

The following is an example:

 public class MyThread extends Thread
  {
   int count= 1, number;
   public MyThread(int num)
   {
    number = num;
    System.out.println
    ("创建线程 " + number);
   }
   public void run() {
    while(true) {
     System.out.println
      ("线程 " + number + ":计数 " + count);
     if(++count== 6) return;
    }
  }
  public static void main(String args[])
  {
   for(int i = 0;i 〈 5; i++) new MyThread(i+1).start();
  }
 }

This method is simple and clear, in line with everyone's habits, but it also has a big shortcoming, that is, if our class has been If a class inherits (for example, the applet must inherit from the Applet class), it can no longer inherit the Thread class. At this time, if we do not want to create a new class ,How should I do it?

We might as well explore a new method: we do not create a subclass of the Thread class, but use it directly, then we can only Passing our method as a parameter to an instance of the Thread class is somewhat similar to a callback function. But Java There is no pointer, we can only pass an instance of the class that contains this method.

So how to restrict this class to include this method? Using the interface of course! (Although abstract classes can also be satisfied, they require inheritance. Isn’t the reason why we should adopt this new method to avoid the restrictions brought by inheritance?)

Java provides Interface java.lang.Runnable to support this method.

Method 2: Implement Runnable Interface

RunnableInterface There is only one method run(). We declare that our class implements the Runnable interface and provides this method to convert our thread code By writing it in, this part of the task is completed. However, the Runnable interface does not have any support for threads. We must also create an instance of the Thread class, which is done through ThreadConstructor of the class public Thread(Runnable target); to implement. The following is an example:

public class MyThread implements Runnable
  {
   int count= 1, number;
   public MyThread(int num)
   {
    number = num;
    System.out.println("创建线程 " + number);
   }
   public void run()
   {
    while(true)
    {
     System.out.println
     ("线程 " + number + ":计数 " + count);
     if(++count== 6) return;
    }
   }
   public static void main(String args[])
   {
    for(int i = 0; i 〈 5;i++) new Thread(new MyThread(i+1)).start();
   }
  }

Strictly speaking, it is also feasible to create an instance of the Thread subclass, but it must be noted that the subclass must not override Thread run method of the class, otherwise the thread will execute the run of the subclass method, rather than the run method of the class we use to implement the Runnable interface, you might as well try it out.

Using Runnable interface to implement multi-threading allows us to contain all code in one class, which is conducive to encapsulation. Its disadvantage is that we Only one set of code can be used. If you want to create multiple threads and have each thread execute different codes, you still have to create additional classes. If this is the case, in most cases, it may be better to directly inherit from multiple classes Thread Comes compactly.

方法三、使用ExecutorService、Callable、Future实现有返回结果的多线程

ExecutorServiceCallableFuture这个对象实际上都是属于Executor框架中的功能类。想要详细了解Executor框架的可以访问http://www.javaeye.com/topic/366591 ,这里面对该框架做了很详细的解释。返回结果的线程是在JDK1.5中引入的新特征,确实很实用,有了这种特征我就不需要再为了得到返回值而大费周折了,而且即便实现了也可能漏洞百出。

可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。下面提供了一个完整的有返回结果的多线程测试例子,在JDK1.5下验证过没问题可以直接使用。代码如下:

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 list = new ArrayList();  
   for (int i = 0; i < taskSize; i++) {  
    Callable c = new MyCallable(i + " ");  
    // 执行任务并获取Future对象  
    Future f = pool.submit(c);  
    // System.out.println(">>>" + 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 {  
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 + "毫秒】";  
}  
}

代码说明:

上述代码中Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定数目线程的线程池。

public static ExecutorService newCachedThreadPool()

创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

public static ExecutorService newSingleThreadExecutor()

创建一个单线程化的Executor

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

综上所述,以上方法各有千秋,大家可以灵活运用。

The above is the detailed content of How to implement multithreading in Java? (code example). For more information, please follow other related articles on the PHP Chinese website!

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