Heim > Java > javaLernprogramm > Hauptteil

Wie implementiert man Multithreading in Java? (Codebeispiel)

青灯夜游
Freigeben: 2019-02-26 16:47:16
nach vorne
4839 Leute haben es durchsucht

Der Inhalt dieses Artikels ist: Wie implementiert man Multithreading in Java? (Codebeispiel) hat einen gewissen Referenzwert. Freunde in Not können darauf verweisen.

Methode 1: Erben Sie die Klasse und überschreiben Sie die Methode run()

Wir überschreiben run() in der Unterklasse der erstellten Thread-Klasse Fügen Sie einfach den Code hinzu, der vom Thread ausgeführt werden soll.

Das Folgende ist ein Beispiel:

 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();
  }
 }
Nach dem Login kopieren

Diese Methode ist einfach und klar und entspricht allen Gewohnheiten. Allerdings hat sie auch einen großen Nachteil, wenn Unsere Klasse wurde von geändert. Wenn eine Klasse erbt (z. B. muss das Applet von der Klasse Applet erben), kann es die Klasse Thread nicht mehr erben Was sollen wir zu diesem Zeitpunkt tun, wenn wir keine neue Klasse erstellen möchten?

Wir könnten genauso gut eine neue Methode erkunden: Wir erstellen keine Unterklasse der Thread-Klasse, sondern verwenden sie direkt, dann können wir nur Übergeben Sie unsere Methode als Parameter an eine Instanz der Thread -Klasse, ähnlich wie eine Rückruffunktion. Aber Java hat keinen Zeiger, wir können nur eine Instanz der Klasse übergeben, die diese Methode enthält.
Wie kann man diese Klasse also darauf beschränken, diese Methode einzuschließen? Natürlich über die Schnittstelle! (Obwohl abstrakte Klassen auch erfüllt werden können, erfordern sie Vererbung. Ist der Grund, warum wir diese neue Methode anwenden, nicht nur, um die durch Vererbung verursachten Einschränkungen zu vermeiden?)


Java

stellt eine Schnittstelle < bereit 🎜>

java.lang.Runnable zur Unterstützung dieser Methode.

Methode 2: Implementieren Sie die Runnable-Schnittstelle Runnable Schnittstelle Es gibt nur eine Methode

run(), wir deklarieren unsere Klasse, um die Schnittstelle Runnable zu implementieren und stellen diese Methode zum Konvertieren unserer bereit Thread-Code Durch das Einschreiben ist dieser Teil der Aufgabe abgeschlossen. Aber die Runnable-Schnittstelle bietet keine Unterstützung für Threads. Wir müssen auch eine Instanz der Thread-Klasse erstellen, was erledigt ist durch ThreadKonstruktor der Klasse public Thread(Runnable target); zur Implementierung. Hier ein Beispiel:

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();
   }
  }
Nach dem Login kopieren
Genau genommen ist es auch möglich, eine Instanz der Unterklasse

Thread

zu erstellen, allerdings muss beachtet werden, dass die Unterklasse dies nicht tun darf überschreibt die Methode Thread der Klasse run , andernfalls führt der Thread die Methode run <🎜 der Unterklasse aus >-Methode anstelle der run -Methode der Klasse, die wir zum Implementieren der Runnable -Schnittstelle verwenden, können Sie sie auch ausprobieren . Die Verwendung der
Runnable

-Schnittstelle zur Implementierung von Multithreading ermöglicht es uns, den gesamten Code in einer Klasse zu enthalten, was für die Kapselung von Vorteil ist. Der Nachteil besteht darin Wenn Sie mehrere Threads erstellen möchten und jeder Thread unterschiedliche Codes ausführen soll, müssen Sie dennoch zusätzliche Klassen erstellen. In den meisten Fällen ist es möglicherweise besser, direkt zu erben aus mehreren Klassen

Thread Kommt kompakt.

方法三、使用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 + "毫秒】";  
}  
}
Nach dem Login kopieren

代码说明:

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

public static ExecutorService newFixedThreadPool(int nThreads)
Nach dem Login kopieren

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

public static ExecutorService newCachedThreadPool()
Nach dem Login kopieren

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

public static ExecutorService newSingleThreadExecutor()
Nach dem Login kopieren

创建一个单线程化的Executor

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
Nach dem Login kopieren

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

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

Das obige ist der detaillierte Inhalt vonWie implementiert man Multithreading in Java? (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:cnblogs.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage