Rumah  >  Artikel  >  Java  >  Empat cara untuk melaksanakan multithreading di Jawa

Empat cara untuk melaksanakan multithreading di Jawa

WBOY
WBOYke hadapan
2022-07-04 13:56:282376semak imbas

Artikel ini membawakan anda pengetahuan yang berkaitan tentang java Ia terutamanya menyelesaikan isu yang berkaitan dengan empat cara untuk melaksanakan berbilang benang, termasuk mewarisi kelas Thread dan melaksanakan antara muka Boleh Panggil melalui pembungkus FutureTask. Untuk mencipta benang Benang, gunakan ExecutorService, Boleh Dipanggil, Masa Depan untuk melaksanakan berbilang benang dengan hasil yang dikembalikan, dsb. Mari kita lihat, saya harap ia akan membantu semua orang.

Empat cara untuk melaksanakan multithreading di Jawa

Pembelajaran yang disyorkan: "tutorial video java"

JavaKaedah pelaksanaan multi-threading Terdapat empat jenis utama:

  • Warisi kelas Thread dan laksanakan antara muka Runnable

  • Laksanakan antara muka Boleh Panggil untuk mencipta benang Thread melalui pembungkus FutureTask

  • Gunakan ExecutorService and Callable

  • Masa depan untuk melaksanakan multi-threading yang mengembalikan hasil

Dua kaedah pertama Dua kaedah pertama tidak mempunyai nilai pulangan selepas urutan dilaksanakan dan dua kaedah terakhir mempunyai nilai pulangan.

1. Empat cara untuk melaksanakan multi-threading

1 Mewarisi kelas Thread untuk mencipta thread

Kelas Thread pada asasnya adalah contoh yang melaksanakan antara muka Runnable dan mewakili. contoh benang. Satu-satunya cara untuk memulakan thread adalah melalui kaedah contoh start() kelas Thread. Kaedah start() ialah kaedah asli yang akan memulakan utas baharu dan melaksanakan kaedah run(). Ia adalah sangat mudah untuk melaksanakan multi-benang dengan cara ini Dengan terus melanjutkan Thread melalui kelas anda sendiri dan mengatasi kaedah run(), anda boleh memulakan thread baru dan melaksanakan kaedah run() anda sendiri. Contohnya:

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 Laksanakan antara muka Runnable untuk mencipta utas

Jika kelas anda telah melanjutkan kelas lain, anda tidak boleh terus melanjutkan Thread Pada masa ini, anda boleh melaksanakan a Antara muka boleh jalan, seperti berikut :

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

Untuk memulakan MyThread, anda perlu membuat instantiat Thread dahulu dan menghantar contoh MyThread anda sendiri:

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

Malah, apabila Parameter sasaran boleh dijalankan dihantar ke Benang Selepas itu, kaedah run() Thread akan memanggil target.run(), rujuk kod sumber JDK:

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

3. Laksanakan antara muka Boleh Panggil untuk mencipta Thread thread melalui pembungkus FutureTask

Antara muka Boleh Panggil (yang hanya mempunyai satu kaedah) ditakrifkan seperti berikut:

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;
    }

}
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();   //至此,一个线程就创建完成了。

4 Gunakan ExecutorService, Callable dan Future untuk dilaksanakan benang yang mengembalikan hasil

ExecutorService, Callable, dan Future Interface sebenarnya tergolong dalam rangka kerja Executor. Benang yang mengembalikan hasil ialah ciri baharu yang diperkenalkan dalam JDK1.5 Dengan ciri ini, anda tidak perlu lagi melalui banyak masalah untuk mendapatkan nilai pulangan. Dan walaupun anda melaksanakannya sendiri, ia mungkin penuh dengan kelemahan.

Tugas yang boleh mengembalikan nilai mesti melaksanakan antara muka Boleh Panggil. Begitu juga, tugas yang tidak mengembalikan nilai mesti melaksanakan antara muka Runnable.

Selepas melaksanakan tugas Boleh Panggil, anda boleh mendapatkan objek Masa Depan Dengan memanggil dapatkan pada objek, anda boleh mendapatkan Objek yang dikembalikan oleh tugas Boleh Panggil.

Nota: Kaedah get disekat, iaitu: benang tidak mengembalikan hasil dan kaedah get akan menunggu selama-lamanya.

Digabungkan dengan antara muka kolam benang ExecutorService, anda boleh merealisasikan pelbagai benang lagenda yang mengembalikan hasil.

Yang berikut menyediakan contoh ujian berbilang benang lengkap dengan hasil yang dikembalikan. Ia telah disahkan di bawah JDK1.5 dan boleh digunakan secara langsung tanpa sebarang masalah. Kodnya adalah seperti berikut:

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 < 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<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 + "毫秒】";  
}  
}

2. Pengetahuan berkaitan pelbagai benang

1.

· Perbezaan utama ialah kaedah jalankan antara muka Runnable tidak mempunyai nilai pulangan; antara muka Boleh Panggil mempunyai nilai pulangan dan menyokong generik Kaedah jalankan antara muka Boleh Panggil hanya boleh membuang pengecualian masa jalan dan tidak boleh menangkap dan mengendalikannya

· Kaedah panggilan antara muka Boleh Panggil membenarkannya; melontar pengecualian dan boleh mendapatkan maklumat pengecualian

2. Bagaimana untuk memulakan utas baharu dan apakah perbezaan antara memanggil kaedah mula dan jalankan?

·

Objek benang memanggil kaedah larian tanpa memulakan benang. Hanya kaedah panggilan objek.

· Panggilan objek utas mula membuka utas dan membenarkan jvm memanggil kaedah larian untuk melaksanakan dalam utas yang dibuka Memanggil kaedah mula boleh memulakan utas dan membuat utas masukkan keadaan sedia, dan kaedah larian hanya Kaedah biasa benang masih dilaksanakan dalam utas utama.

3. Kaedah asas berkaitan benang?

Kaedah asas yang berkaitan dengan urutan termasuk tunggu, maklumkan, maklumkanSemua, tidur, sertai, hasil, dll.

·

Benang menunggu (tunggu) Urutan yang memanggil kaedah ini Memasuki keadaan menunggu, ia hanya akan kembali jika ia menunggu pemberitahuan daripada utas lain atau diganggu Perlu diingat bahawa selepas memanggil kaedah tunggu(), kunci objek akan dilepaskan. Oleh itu, kaedah tunggu biasanya digunakan dalam kaedah disegerakkan atau blok kod disegerakkan.

· Tidur benang (tidur) menyebabkan utas semasa tidur Berbeza daripada kaedah tunggu, tidur tidak akan melepaskan kunci yang sedang diduduki(lama) akan menyebabkan benang itu masukkan keadaan TIMED-WATING, dan kaedah wait() akan menyebabkan urutan semasa memasuki keadaan WATING.

· Hasil benang (hasil) akan menyebabkan benang semasa menghasilkan kepingan masa pelaksanaan CPU dan bersaing semula dengan benang lain untuk kepingan masa CPU. Secara umumnya, benang dengan keutamaan tinggi mempunyai peluang yang lebih besar untuk berjaya bersaing untuk potongan masa CPU, tetapi ini tidak mutlak Sesetengah sistem pengendalian tidak sensitif kepada keutamaan benang.

· Gangguan benang (gangguan) Mengganggu benang bertujuan untuk memberi isyarat pemberitahuan kepada benang, yang akan menjejaskan bendera gangguan di dalam benang. Urutan ini sendiri tidak akan mengubah keadaan (seperti menyekat, penamatan, dll.)

· Sertai menunggu urutan lain menamatkan kaedah join(), menunggu urutan lain ditamatkan , dan memanggilnya dalam utas semasa Kaedah join() thread akan menukarkan thread semasa kepada keadaan disekat dan kembali ke thread lain untuk menamatkan thread semasa kemudiannya akan bertukar daripada keadaan disekat kepada keadaan sedia, menunggu kelebihan CPU.

· Pengedaran benang (beritahu) Kaedah notify() dalam kelas Object membangunkan satu utas menunggu pada monitor objek ini menunggu pada objek ini, salah satu utas akan dipilih untuk bangun Pilihannya adalah sewenang-wenangnya, dan berlaku apabila keputusan pelaksanaan dibuat, utas menunggu pada monitor objek dengan memanggil salah satu kaedah wait() itu tidak boleh meneruskan pelaksanaan sehingga benang semasa melepaskan kunci pada objek ini dan dibangkitkan benang akan bersaing dengan cara biasa dengan semua benang lain secara aktif menyegerakkan pada objek. Kaedah yang sama ialah notifyAll(), yang membangkitkan semua benang menunggu di monitor semula.

5. Apakah perbezaan antara tunggu() dan tidur()?

· ① Dari kelas yang berbeza tunggu(): dari kelas Objek tidur (): daripada kelas Utas; Mengenai pelepasan kunci: tunggu(): Kunci akan dilepaskan semasa proses menunggu; sleep(): Kunci tidak akan dilepaskan semasa proses menunggu

· ③ Skop use: wait(): mesti digunakan dalam blok kod yang disegerakkan; sleep(): boleh digunakan di mana-mana sahaja; ; tidur (): Pengecualian perlu ditangkap;

6 Prinsip berbilang benang

Prinsip berbilang benang: Berbilang benang ialah. dilakukan melalui concurrency

. Untuk CPU, ia hanya boleh melaksanakan satu program pada masa tertentu, iaitu, ia hanya boleh menjalankan satu proses pada masa yang sama CPU akan terus bertukar antara proses ini, dan setiap utas akan dilaksanakan untuk satu masa. Oleh kerana kelajuan pelaksanaan CPU adalah terlalu pantas berbanding persepsi kami, walaupun CPU memutarkan pelaksanaan antara pelbagai proses, kami merasakan seolah-olah berbilang proses dilaksanakan pada masa yang sama.

CPU akan bertukar antara berbilang proses Jika kita membuka terlalu banyak program, masa yang diambil untuk CPU beralih kepada setiap proses juga akan menjadi lebih lama, dan kita juga akan merasakan bahawa mesin berjalan lebih perlahan. Oleh itu, penggunaan multi-benang yang munasabah boleh meningkatkan kecekapan, tetapi penggunaan yang meluas tidak membawa kita peningkatan dalam kecekapan.

Teknologi multi-threading terutamanya menyelesaikan masalah pelaksanaan berbilang benang dalam unit pemproses Ia boleh mengurangkan masa melahu unit pemproses dengan ketara dan meningkatkan kapasiti pemprosesan unit pemproses.

Pembelajaran yang disyorkan: "

tutorial video java
"

Atas ialah kandungan terperinci Empat cara untuk melaksanakan multithreading di Jawa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:csdn.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam