Rumah  >  Artikel  >  Java  >  Analisis contoh penghalang gelung pengaturcaraan serentak Java CyclicBarrier

Analisis contoh penghalang gelung pengaturcaraan serentak Java CyclicBarrier

WBOY
WBOYke hadapan
2023-05-18 23:19:27725semak imbas

CyclicBarrier

CountDownLatch yang diperkenalkan sebelum ini telah dioptimumkan dalam menyelesaikan penyegerakan berbilang utas berbanding kaedah gabungan untuk memanggil utas. Walau bagaimanapun, kaunter CountDownLatch adalah sekali sahaja, iaitu selepas nilai kaunter mencapai 0, memanggil kaedah tunggu dan kira detik CountDownLatch akan kembali serta-merta, yang tidak akan mencapai kesan penyegerakan benang. Oleh itu, untuk memenuhi keperluan kaunter ditetapkan semula, pasukan pembangunan JDK menyediakan kelas CyclicBarrier dan fungsi kelas CyclicBarrier tidak terhad kepada fungsi CountDownLatch. Difahamkan secara literal, CyclicBarrier bermaksud halangan gelung, yang membenarkan sekumpulan utas untuk semua mencapai keadaan dan kemudian melaksanakan semuanya pada masa yang sama. Sebab mengapa ia dipanggil loopback ialah ia boleh digunakan semula selepas semua utas menunggu selesai dilaksanakan dan keadaan CyclicBarrier ditetapkan semula. Ia dipanggil penghalang kerana benang akan disekat selepas memanggil kaedah menunggu ini dipanggil titik halangan Selepas semua benang memanggil kaedah menunggu, benang akan menembusi halangan dan terus berjalan ke bawah. Sebelum memperkenalkan prinsip, kami akan memperkenalkan beberapa contoh untuk mendalami pemahaman kami. Dalam contoh berikut, perkara yang ingin kita capai ialah menggunakan dua utas untuk melaksanakan tugasan A yang terurai, dan kemudian meringkaskan keputusannya selepas dua utas menyelesaikan tugasan mereka.

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CycleBarrierTest {

   
   //创建一个线程数固定为2的线程池
   private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
       @Override
       public void run() {
           System.out.println(Thread.currentThread() + " task1 merge result");
       }
   });

   public static void main(String[] args) throws InterruptedException{
       ExecutorService executorService = Executors.newFixedThreadPool(2);

       
       //添加线程A到线程池
       executorService.submit(new Runnable() {
           @Override
           public void run() {
               try {
                   System.out.println(Thread.currentThread() + "task1");
                   System.out.println(Thread.currentThread() + "enter in  barrier");
                   cyclicBarrier.await();
                   System.out.println(Thread.currentThread() + "enter out  barrier");
               } catch (Exception e) {
                   e.printStackTrace();
               }
           }
       });

       //添加线程B到线程池
       executorService.submit(new Runnable() {
           @Override
           public void run() {
               try {
                   System.out.println(Thread.currentThread() + "task2");
                   System.out.println(Thread.currentThread() + "enter in  barrier");
                   cyclicBarrier.await();
                   System.out.println(Thread.currentThread() + "enter out  barrier");
               } catch (Exception e) {
                   e.printStackTrace();
               }
           }
       });

       //关闭线程池
       executorService.shutdown();

   }
}

Analisis contoh penghalang gelung pengaturcaraan serentak Java CyclicBarrier

Kod di atas mencipta objek CyclicBarrier, parameter pertamanya ialah nilai awal pembilang, dan nombor kedua Runable ialah tugas yang perlu dilakukan apabila nilai kiraan ialah 0 . Dalam fungsi utama, kumpulan benang bersaiz 2 mula-mula dibuat. Tambahkan dua subtugas pada kumpulan benang, dan setiap subtugas akan memanggil kaedah ini selepas melengkapkan logiknya sendiri. Pada mulanya, nilai pembilang ialah 2. Apabila utas pertama memanggil kaedah tunggu, nilai pembilang akan dikurangkan kepada 1. Oleh kerana nilai pembilang bukan 0 pada masa ini, utas semasa mencapai titik halangan dan disekat. Kemudian apabila panggilan benang kedua menunggu, ia akan memasuki penghalang dan nilai pembilang juga akan dikurangkan Sekarang nilai pembilang ialah 0. Pada masa ini, ia akan melaksanakan tugas dalam pembina CyclicBarrier Selepas pelaksanaan selesai akan keluar dari titik penghalang dan membangunkan benang Kedua yang disekat. Pada masa ini, benang pertama juga akan keluar dari titik halangan dan terus berjalan ke bawah.

Contoh di atas menggambarkan bahawa beberapa utas sedang menunggu antara satu sama lain Jika nilai pembilang ialah N, maka utas N1 yang kemudiannya memanggil kaedah tunggu akan disekat kerana ia mencapai titik penghalang Selepas memanggil tunggu, nilai pembilang ialah 0. Pada masa ini, utas Nth akan menghantar pemberitahuan untuk membangunkan utas N1 sebelumnya. Maksudnya, apabila semua benang mencapai titik halangan, mereka boleh terus melaksanakan ke bawah bersama-sama. Contoh ini boleh mencapai output yang serupa dengan menggunakan CountDownLatch. Mari kita berikan satu lagi contoh untuk menggambarkan kebolehgunaan semula CyclicBarrier.

Andaikan bahawa tugasan terdiri daripada Fasa 1, Fasa 2 dan Fasa 3. Setiap urutan mesti melaksanakan Fasa 1, Fasa 2 dan Fasa 3 secara bersiri Apabila berbilang rangkaian melaksanakan tugasan, semua pelaksanaan Fasa 2 hanya boleh dimasukkan selepas fasa 1 semua utas selesai, dan pelaksanaan fasa 3 boleh dimasukkan hanya selepas fasa 2 semua utas selesai. CyclicBarrier digunakan di bawah untuk mencapai keperluan ini.

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CycleBarrierTest1 {

    //创建一个线程数固定为2的线程池
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);

    public static void main(String[] args) throws InterruptedException{
        ExecutorService executorService = Executors.newFixedThreadPool(2);


        //添加线程A到线程池
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread() + "step1");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + "step2");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + "step3");
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        //添加线程B到线程池
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread() + "step1");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + "step2");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread() + "step3");
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        //关闭线程池
        executorService.shutdown();

    }
}

Analisis contoh penghalang gelung pengaturcaraan serentak Java CyclicBarrier

Dalam kod di atas, setiap sub-utas memanggil kaedah tunggu selepas melaksanakan fasa 1. Ia menunggu sehingga semua utas mencapai titik halangan sebelum melaksanakan bersama-sama semua utas telah menyelesaikan fasa 1 sebelum mereka mula melaksanakan fasa 2.

Atas ialah kandungan terperinci Analisis contoh penghalang gelung pengaturcaraan serentak Java CyclicBarrier. 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