Rumah  >  Artikel  >  Java  >  Bagaimanakah Java menggunakan kolam benang? Pelaksanaan kod.

Bagaimanakah Java menggunakan kolam benang? Pelaksanaan kod.

WBOY
WBOYke hadapan
2023-05-08 14:31:071875semak imbas

Prinsip Teras Kolam Benang Java

Semua orang yang telah membaca kod sumber kumpulan benang Java mengetahui bahawa kelas teras dalam kolam benang Java ialah ThreadPoolExecutor, dan kaedah pembinaan teras dalam kelas ThreadPoolExecutor adalah untuk membawa Terdapat kaedah pembina dengan 7 parameter seperti yang ditunjukkan di bawah.

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

Maksud setiap parameter adalah seperti berikut.

  • corePoolSize: Bilangan utas teras pemastautin dalam kumpulan benang.

  • maximumPoolSize: Kumpulan benang boleh menampung bilangan maksimum urutan yang dilaksanakan secara serentak Nilai ini lebih besar daripada atau sama dengan 1.

  • keepAliveTime: Masa kemandirian lebihan benang melahu Apabila masa ruang mencapai nilai keepAliveTime, lebihan benang akan dimusnahkan sehingga hanya corePoolSize benang yang tinggal.

  • unit: unit keepAliveTime.

  • workQueue: Barisan tugas, tugasan yang telah diserahkan tetapi belum dilaksanakan.

  • threadFactory: Mewakili kilang benang yang menjana benang pekerja dalam kumpulan benang Apabila pengguna mencipta benang baharu, nilai lalai secara amnya mencukupi.

  • pengendali: Strategi penolakan, menunjukkan cara menolak strategi pelaksanaan permintaan boleh jalan apabila baris gilir benang penuh dan benang pekerja lebih besar daripada atau sama dengan bilangan maksimum yang dipaparkan bagi kumpulan benang (maxnumPoolSize).

Dan kumpulan benang Java dilaksanakan melalui model pengeluar-pengguna Pengguna kumpulan benang ialah pengeluar, dan kumpulan benang itu sendiri ialah pengguna. .

Aliran kerja teras kumpulan benang Java ditunjukkan dalam rajah di bawah.

Bagaimanakah Java menggunakan kolam benang? Pelaksanaan kod.

Kolam benang Java buatan tangan

Kolam benang yang kami laksanakan secara manual jauh lebih mudah daripada kumpulan benang Java sendiri Kami telah mengalih keluar semua jenis kerumitan kaedah pemprosesan hanya mengekalkan prinsip teras: pengguna kumpulan benang menambah tugasan pada baris gilir tugas, dan kumpulan benang itu sendiri menggunakan tugas daripada baris gilir tugas dan melaksanakan tugas.

Bagaimanakah Java menggunakan kolam benang? Pelaksanaan kod.

Selagi anda memahami prinsip teras ini, kod seterusnya akan menjadi lebih mudah. Apabila melaksanakan kumpulan benang mudah ini, kami boleh membongkar keseluruhan proses pelaksanaan. Proses pelaksanaan yang dibongkar ialah: mentakrifkan medan teras, mencipta WorkThread kelas dalaman, mencipta pembina kelas ThreadPool dan mencipta kaedah untuk melaksanakan tugas.

Tentukan medan teras

Mula-mula, kami mencipta kelas Java bernama ThreadPool dan mentakrifkan medan teras berikut dalam kelas ini.

  • DEFAULT_WORKQUEUE_SIZE: Pemalar statik, menunjukkan saiz baris gilir menyekat lalai.

  • workQueue: mensimulasikan kumpulan benang sebenar menggunakan baris gilir menyekat untuk melaksanakan model pengeluar-pengguna.

  • workThreads: Simulasikan kumpulan benang sebenar dan gunakan koleksi Senarai untuk menyimpan utas yang berfungsi di dalam kumpulan benang.

Kod teras adalah seperti berikut.

//默认阻塞队列大小
private static final int DEFAULT_WORKQUEUE_SIZE = 5;

//模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
private BlockingQueue<Runnable> workQueue;

//模拟实际的线程池使用List集合保存线程池内部的工作线程
private List<WorkThread> workThreads = new ArrayList<WorkThread>();

Buat WordThread kelas dalam

Buat WorkThread kelas dalam dalam kelas ThreadPool untuk mensimulasikan benang pekerja dalam kumpulan benang. Fungsi utama adalah untuk menggunakan tugas dalam workQueue dan melaksanakan tugas. Memandangkan utas pekerja perlu terus mendapatkan tugas daripada workQueue, gelung sementara (benar) digunakan di sini untuk mencuba secara berterusan menggunakan tugas dalam baris gilir.

Kod teras adalah seperti berikut.

//内部类WorkThread,模拟线程池中的工作线程
//主要的作用就是消费workQueue中的任务,并执行
//由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
class WorkThread extends Thread{
    @Override
    public void run() {
        //不断循环获取队列中的任务
        while (true){
            //当没有任务时,会阻塞
            try {
                Runnable workTask = workQueue.take();
                workTask.run();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Buat pembina kelas ThreadPool

Di sini, kami mencipta dua pembina untuk kelas ThreadPool Dalam satu pembina, kapasiti kumpulan benang dan baris gilir menyekat dimasukkan, dan dalam pembina lain Hanya kapasiti kumpulan benang yang dihantar masuk.

Kod teras adalah seperti berikut.

//在ThreadPool的构造方法中传入线程池的大小和阻塞队列
public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
    this.workQueue = workQueue;
    //创建poolSize个工作线程并将其加入到workThreads集合中
    IntStream.range(0, poolSize).forEach((i) -> {
        WorkThread workThread = new WorkThread();
        workThread.start();
        workThreads.add(workThread);
    });
}

//在ThreadPool的构造方法中传入线程池的大小
public ThreadPool(int poolSize){
    this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
}

Buat kaedah untuk melaksanakan tugas

Buat kaedah execute() dalam kelas ThreadPool Pelaksanaan kaedah execute() adalah agak mudah, iaitu menambah tugas Runnable yang diterima dengan kaedah untuk dalam baris gilir kerja.

Kod teras adalah seperti berikut.

//通过线程池执行任务
public void execute(Runnable task){
    try {
        workQueue.put(task);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Kod sumber penuh

Di sini, kami memberikan kod sumber lengkap kumpulan benang ThreadPool yang dilaksanakan secara manual, seperti yang ditunjukkan di bawah.

package io.binghe.thread.pool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 自定义线程池
 */
public class ThreadPool {

    //默认阻塞队列大小
    private static final int DEFAULT_WORKQUEUE_SIZE = 5;

    //模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
    private BlockingQueue<Runnable> workQueue;

    //模拟实际的线程池使用List集合保存线程池内部的工作线程
    private List<WorkThread> workThreads = new ArrayList<WorkThread>();

    //在ThreadPool的构造方法中传入线程池的大小和阻塞队列
    public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
        this.workQueue = workQueue;
        //创建poolSize个工作线程并将其加入到workThreads集合中
        IntStream.range(0, poolSize).forEach((i) -> {
            WorkThread workThread = new WorkThread();
            workThread.start();
            workThreads.add(workThread);
        });
    }

    //在ThreadPool的构造方法中传入线程池的大小
    public ThreadPool(int poolSize){
        this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
    }

 //通过线程池执行任务
    public void execute(Runnable task){
        try {
            workQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //内部类WorkThread,模拟线程池中的工作线程
    //主要的作用就是消费workQueue中的任务,并执行
    //由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
    class WorkThread extends Thread{
        @Override
        public void run() {
            //不断循环获取队列中的任务
            while (true){
                //当没有任务时,会阻塞
                try {
                    Runnable workTask = workQueue.take();
                    workTask.run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Ya, kami hanya menggunakan berdozen baris kod Java untuk melaksanakan versi minimalis kumpulan benang Java Ya, kod kumpulan benang Java versi minimalis ini merangkumi prinsip teras Java .

Seterusnya, mari kita uji versi minimalis kumpulan benang Java ini.

Menulis program ujian

Program ujian juga agak mudah, iaitu, dengan memanggil pembina kelas ThreadPool dalam kaedah main() , menghantar saiz kumpulan benang , dan mencipta contoh kelas ThreadPool Kemudian kaedah execute() kelas ThreadPool dipanggil 10 kali dalam gelung dan tugasan yang diserahkan kepada kumpulan benang ialah: 打印当前线程的名称--->> Hello ThreadPool.

Kod ujian keseluruhan adalah seperti berikut.

package io.binghe.thread.pool.test;

import io.binghe.thread.pool.ThreadPool;

import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 测试自定义线程池
 */
public class ThreadPoolTest {

    public static void main(String[] args){
        ThreadPool threadPool = new ThreadPool(10);
        IntStream.range(0, 10).forEach((i) -> {
            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "--->> Hello ThreadPool");
            });
        });
    }
}

Seterusnya, jalankan kaedah main() kelas ThreadPoolTest, dan maklumat berikut akan dikeluarkan.

Benang-0--->> Hello ThreadPool
Thread-9--->> Hello ThreadPool
Thread-5--->> Hello ThreadPool
Thread-8--->> Hello ThreadPool
Thread-4--->> Hello ThreadPool
Thread-1--->> Hello ThreadPool
Thread-2--->> Hello ThreadPool
Thread-5--->> Hello ThreadPool
Thread-9--->> Hello ThreadPool
Thread-0--->> Hello ThreadPool

Atas ialah kandungan terperinci Bagaimanakah Java menggunakan kolam benang? Pelaksanaan kod.. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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