Back-end öğrencilerin geliştirme sırasında az çok iş parçacıklı geliştirmeyi içereceğine inanıyorum.Java geliştirme olarak, sıklıkla çok iş parçacıklı geliştirme kullanıyorum.
Java dilinin multithreading ile başa çıkmada çok iyi olduğunu düşünüyorum. İş parçacıkları oluşturmak, başlatmak ve yönetmek için kısa kod kullanabiliriz.
Söyleyecek fazla bir şey yok, hadi aşağıdan ayrıntılı olarak bir göz atalım! ! !
Bu eski moda bir sorudur. Bir arka uç programcısı olarak, iş parçacıkları ve süreçler arasındaki farkı ayırt etmeliyiz. Hemen hemen tüm işletim sistemleri "süreç" kavramına sahiptir!
Bir görev, bir program, her çalışan program bir süreçtir!
Program çalışırken, birden çok sıralı yürütme akışı içerir ve her sıralı yürütme akışı bir iş parçacığıdır!
Süreç aşağıdaki üç özelliğe sahiptir:
Çoklu iş parçacığı, çoklu süreç kavramını genişletir, böylece aynı süreç aynı anda birden fazla görevi yerine getirebilir. İş parçacığı, Hafif İşlem olarak da bilinir ve iş parçacığı, sürecin yürütme birimidir. Bir işlemin bir işletim sistemindeki konumu gibi, iş parçacıkları bağımsızdır ve bir programdaki eşzamanlı yürütme akışlarıdır. İşlem başlatıldığında, ana iş parçacığı oluşturulur. Çoğu uygulama için, genellikle yalnızca bir ana iş parçacığı gereklidir, ancak işlemde birden çok sıralı yürütme akışı da oluşturulabilir.Bu sıralı yürütme akışları evrelerdir ve her iş parçacığı birbirinden bağımsızdır.
Bir iş parçacığı, bir sürecin ayrılmaz bir parçasıdır. Bir işlemin birden çok iş parçacığı olabilir ve bir iş parçacığının bir üst süreç olması gerekir. Bir iş parçacığı kendi yığınına, kendi program sayacına ve kendi yerel değişkenlerine sahip olabilir, ancak kendi sistem kaynaklarına sahip değildir ve sürecin sahip olduğu tüm kaynakları üst sürecin diğer evreleriyle paylaşır.
En basit ifadeyle, bir program çalıştırıldıktan sonra en az bir işlem vardır Bir süreç birden fazla evre içerebilir, ancak en az bir evre dahil edilmelidir.
Java, evreleri temsil etmek için Thread sınıfını kullanır ve tüm evre nesneleri, Thread sınıfının veya alt sınıflarının örnekleri olmalıdır.
Oluşturmak ve başlamak için Thread sınıfını devralın
Görev. Bu nedenle, run () yöntemine iş parçacığı yürütme gövdesi adı verilir.
Toplam üç iş parçacığı, bir ana iş parçacığı ve iki alt iş parçacığı çalıştırın!
Ana iş parçacığının yürütme gövdesi run () yöntemi tarafından değil, ana yöntem tarafından belirlenir Ana yöntemin yöntem gövdesi, ana iş parçacığının iş parçacığı yürütme gövdesini temsil eder.
çok dikkat:
Thread sınıfı yöntemini miras alarak bir iş parçacığı sınıfı oluştururken, birden çok iş parçacığı, evre sınıfının örnek değişkenlerini paylaşamaz.
Runnable nesnesi yalnızca Thread nesnesinin hedefi olarak işlev görür ve Runnable uygulama sınıfında bulunan run () yöntemi yalnızca iş parçacığı yürütme gövdesi olarak işlev görür. Gerçek iş parçacığı nesnesi hala bir Thread örneğidir, ancak Thread evre, hedefinin run () yöntemini yürütmekten sorumludur.
public class Main, Runnable { / ** * * @param args * / public static void main (String args) { // İpliğin adını al System.out.println ("Konu adı:" + Thread.currentThread (). GetName ()); Ana ana = yeni Ana (); yeni Konu (ana, "Birinci Konu"). start (); yeni Konu (ana, "Konu İKİ"). start (); } @Override public void run () { for (int i = 0; i < 100; i ++) { System.out.println (Thread.currentThread (). GetName ()); } } }İki iş parçacığı başlatın ve her döngü için 100 kez İplik Adı yazdırın.
Java5'ten başlayarak Java, iş parçacığı yürütme gövdesi olarak kullanılabilen bir call () yöntemi sağlayan Callable arabirimini sağlar, ancak call () yöntemi run () yönteminden daha güçlüdür.
Bu nedenle, Dişlinin hedefi olarak Çağrılabilir bir nesne sağlamak mümkündür ve evrenin evre yürütme gövdesi, Çağrılabilir nesnenin call () yöntemidir. Sorun şudur: Çağrılabilir arabirim, Java 5'te yeni bir arabirimdir ve Çalıştırılabilir arabirimin bir alt arabirimi değildir, bu nedenle Çağrılabilir nesne, İş Parçacığının hedefi olarak doğrudan kullanılamaz.
Java 5, Callable arabiriminde call () yönteminin dönüş değerini temsil etmek için Future arabirimini sağlar ve Future arabirimini uygulayan ve Runnable arabirimini uygulayan Future arabirimi için bir FutureTask uygulama sınıfı sağlar. Thread sınıfının hedefi olarak kullanılabilir. . Çağrılabilir arabirimin genel kısıtlamalara sahip olduğunu ve Çağrılabilir arabirimdeki genel parametre türünün, call () yönteminin dönüş değeri türüyle aynı olduğunu belirtmek gerekir. Ve Çağrılabilir arabirim işlevsel bir arabirim olduğundan, Lambda ifadelerini Çağrılabilir nesneler oluşturmak için kullanabilirsiniz.
Dönüş değeri olan bir iş parçacığı oluşturma ve başlatma adımları:
İplik dizisi tamamlandığında, geri dönün!
Yukarıdaki programda, Lambda ifadesi doğrudan Çağrılabilir nesneyi yaratmak için kullanılır, bu nedenle önce Çağrılabilir uygulama sınıfını ve ardından Çağrılabilir nesneyi yaratmaya gerek yoktur. Callable arabiriminin uygulanması ile Runnable arabiriminin uygulanması arasında çok fark yoktur, ancak Callable'ın call () yöntemi bildirimin bir istisna atmasına izin verir ve dönüş değerine izin verir.
Çok iş parçacıklı okuma, Thread sınıfını miras alarak veya Çalıştırılabilir ve Çağrılabilir arayüzleri uygulayarak elde edilebilir, ancak Çalıştırılabilir arayüz ve Çağrılabilir arayüzü uygulama yolu temelde aynıdır, ancak Çağrılabilir arayüzde tanımlanan metotların dönüş değerlerine sahip olması ve istisnaları bildirebilmesi dışında. Bu nedenle, Çalıştırılabilir arayüzün uygulanması ve Çağrılabilir arayüzün uygulanması aynı şekilde anlaşılabilir!
Çalıştırılabilir ve Çağrılabilir arayüzleri uygulayarak çoklu okuma oluşturmanın avantajları ve dezavantajları:
Bu nedenle, birden çok iş parçacığı oluşturmak için Çalıştırılabilir arabirimin ve Çağrılabilir arabirimin uygulanması önerilir.
İş parçacığı oluşturulup başlatıldığında, ne başlar başlamaz yürütme durumuna girmez, ne de her zaman yürütme durumunda değildir İş parçacığının yaşam döngüsünde, Yeni, Çalıştırılabilir ve Çalışıyor olması gerekir. , Engellendi ve Ölü (5 durum). Özellikle bir iş parçacığı başlatıldığında, CPU'nun tek başına çalışması için her zaman "meşgul" olamaz, bu nedenle CPU birden çok iş parçacığı arasında geçiş yapmak zorundadır, bu nedenle iş parçacığı durumu birden çok kez çalıştırma ve engelleme arasında geçiş yapacaktır.
Yeni statü
Yeni anahtar kelime ile oluşturulan iş parçacığı sonrasında, iş parçacığı şu anda yeni oluşturulmuş durumdadır! İş parçacığının yürütme gövdesi çalıştırılmayacak!
Hazır durum
İş parçacığı nesnesi start () yöntemini çağırdığında, iş parçacığı hazır durumdadır ve Java sanal makinesi bunun için bir yöntem çağrı yığını ve program sayacı oluşturur.Bu durumdaki iş parçacığı çalışmaya başlamaz, sadece iş parçacığının çalışabileceği anlamına gelir. İş parçacığının ne zaman çalışmaya başladığına gelince, bu, iş parçacığı zamanlayıcısının JVM'deki zamanlamasına bağlıdır.
İşletim durumu
İş parçacığı hazır durumundaysa ve CPU'yu elde etmişse, run () içindeki yöntem gövdesini yürütmeye başlar ve ardından iş parçacığı çalışma durumundadır!
Engelleme durumu
İş parçacığı çalışma durumunda olduğunda, iş parçacığı çalışırken kesilmesi gerekiyorsa, diğer iş parçacıkları yürütme şansı elde edebilir. Tüm modern masaüstü ve sunucu işletim sistemleri, önleyici zamanlama stratejileri kullanır, ancak cep telefonları gibi bazı küçük cihazlar, işbirliğine dayalı planlama stratejileri kullanabilir. Böyle bir sistemde, yalnızca bir iş parçacığı uyku () veya verim () Yöntem işgal edilen kaynaklardan vazgeçecektir - yani iş parçacığı aktif olarak işgal edilen kaynaklardan vazgeçmelidir.
Aşağıdaki koşullar oluştuğunda, iş parçacığı bloke durumdadır:
Engellenen iş parçacığı, uygun olduğunda hazır durumuna yeniden girecektir.
Aşağıdaki durumlarda, iş parçacığı tekrar gerekli durumda olacaktır:
İplik ölümü
İplik aşağıdaki üç şekilde bitecek ve bittikten sonra da ölecektir.
Yaşam döngüsü akış şeması aşağıdaki gibidir:
Java'nın iş parçacığı desteği, iş parçacıklarının yürütülmesini denetlemek için bazı kullanışlı araçlar ve yöntemler sağlar.
konuya katıl
Thread, bir iş parçacığının başka bir iş parçacığının join () yöntemini tamamlamasını beklemesi için bir yöntem sağlar. Belirli bir program yürütme akışında başka bir iş parçacığının join () yöntemi çağrıldığında, çağrılan iş parçacığı join () yöntemi ile birleştirilen birleştirme iş parçacığı yürütülene kadar engellenir.
Join () yöntemi genellikle büyük sorunu birçok küçük soruna bölmek için evreler kullanan programlar tarafından çağrılır ve her küçük soruna bir iş parçacığı atanır. Tüm küçük sorunlar çözüldüğünde, diğer işlemler için ana iş parçacığını arayın.
public class JoinThread, Thread'ı genişletiyor {
/ ** * * @param args * / public static void main (String args) { new JoinThread ("threadA"). start (); for (int i = 0; i < 100; i ++) { eğer (i == 20) { JoinThread joinThread = new JoinThread ("konuya katıldı"); joinThread.start (); Deneyin { joinThread.join (); } catch (InterruptedException e) { e.printStackTrace (); } } } System.out.println ("Ana iş parçacığı"); } / ** * Ayar iş parçacığı adını oluştur * * @param threadName * / public JoinThread (String threadName) { süper (threadName); } @Override public void run () { System.out.println ("İş Parçacığı adı:" + getName ()); } }Yukarıdaki koddan ve çalışan sonuçlardan, en son yazdırılan ana iş parçacığının, ana iş parçacığının yürütülmeden önce "birleştirilmiş iş parçacığı" nın yürütülmesini beklemesi gerektiği anlamına geldiğini görmek zor değildir!
Birleştirme iş parçacığını aşırı yüklemenin üç yolu vardır:
Arka plan iş parçacığı tam anlamıyla görülebilir Arka planda çalışan bir iş parçacığıdır Arka plan iş parçacığının bir özelliği vardır: tüm ön plan iplikleri ölürse, arka plan iş parçacığı otomatik olarak ölür. Belirtilen evreyi bir arka plan iş parçacığı olarak ayarlamak için, Thread nesnesinde setDaemon (true) yöntemini çağırabilirsiniz.
Kod simülasyonu:
public class ThreadTest, Thread { / ** * * @param args * / public static void main (String args) { ThreadTest threadTest = new ThreadTest (); // Arka plan dizisi olarak ayarla threadTest.setDaemon (true); threadTest.start (); for (int i = 0; i < 10; i ++) { System.out.println ("Ana iş parçacığı"); } } @Override public void run () { for (int i = 0; i < 100; i ++) { System.out.println ("thread run" + i); } } }Main - ana iş parçacığı yürütülmeyi bitirdiğinde, alt iş parçacığı da döngüye devam etmeden sona erer! Ayrıca Thread, belirtilen iş parçacığının bir arka plan iş parçacığı olup olmadığını belirlemek için isDaemon () yöntemini de sağlar!
Ön plan iş parçacığının ölümünden sonra, JVM'nin ölümün arka plan iş parçacığını bildireceği, ancak yanıt vermek için talimatlar aldığı andan itibaren belirli bir süre alacağı unutulmamalıdır. Ve bir iş parçacığını arka plan iş parçacığı olarak ayarlamak için, iş parçacığı başlatılmadan önce ayarlanmalıdır, yani start () yönteminden önce setDaemon (true) çağrılmalıdır, aksi takdirde IllegalThreadStateException atılır.
Bunun anlaşılması kolaydır, yani iş parçacığının askıya alınmış duruma geçmesine izin verin Thread, iş parçacığının ne kadar süre uyuyacağını milisaniye cinsinden belirleyebilen sleep () yöntemini sağlar.
public class ThreadTest, Thread { / ** * * @param args * / public static void main (String args) { //IP oluşurmak ThreadTest threadTest = new ThreadTest (); // İlçeyi başlat threadTest.start (); } @Override public void run () { for (int i = 0; i < 10; i ++) { System.out.println ("thread run" + i); Deneyin { // Bir saniye uyuduktan sonra sırayla çalışmaya devam edin Thread.sleep (1000); } catch (InterruptedException e) { e.printStackTrace (); } } } }Verim () yöntemi, sleep () yöntemine benzer bir yöntemdir.Ayrıca, Thread sınıfı tarafından sağlanan statik bir yöntemdir.Ayrıca, şu anda yürütülen iş parçacığını askıya alabilir, ancak iş parçacığını engellemez, yalnızca iş parçacığını değiştirir Hazır durumuna gidin. Yield () sadece mevcut iş parçacığını duraklatır ve sistemin iş parçacığı zamanlayıcısının onu yeniden planlamasını sağlar.Bir iş parçacığı askıya almak için getiri () yöntemini çağırdığında, iş parçacığı zamanlayıcının onu yeniden yürütmek üzere programlaması tamamen mümkündür.
Vaka kodu
public class ThreadTest, Thread { / ** * * @param args * / public static void main (String args) { ThreadTest threadTest1 = new ThreadTest ("Thread ONE"); threadTest1.start (); ThreadTest threadTest2 = new ThreadTest ("Konu İKİ"); threadTest2.start (); } public ThreadTest (String threadName) { süper (threadName); } @Override public void run () { for (int i = 0; i < 100; i ++) { System.out.println (getName () + i); // i 20'ye eşit olduğunda, iş parçacığı tavizleri verin eğer (i == 20) { Thread.yield (); } } } }Thread sınıfı, belirtilen iş parçacığının önceliğini ayarlamak ve döndürmek için setPriority (int newPriority) ve getPriority () yöntemleri sağlar. SetPriority () yönteminin parametresi 1 ile 10 arasında değişen bir tam sayı olabilir veya Thread sınıfını kullanabilirsiniz Aşağıdaki üç statik sabit.
public class ThreadTest, Thread { / ** * * @param args * / public static void main (String args) { ThreadTest threadTest1 = new ThreadTest ("Yüksek Öncelik"); // Önceliği ayarla threadTest1.setPriority (MAX_PRIORITY); threadTest1.start (); ThreadTest threadTest2 = new ThreadTest ("düşük öncelikli"); // Önceliği ayarla threadTest1.setPriority (NORM_PRIORITY); threadTest2.start (); } public ThreadTest (String threadName) { süper (threadName); } @Override public void run () { for (int i = 0; i < 100; i ++) { System.out.println (getName () + i); // i 20'ye eşit olduğunda, iş parçacığı tavizleri verin eğer (i == 20) { Thread.yield (); } } } }Kısacası, setPriority değeri ne kadar yüksekse, iş parçacığı o kadar fazla yürütme fırsatı elde eder! Değeri doğrudan ayarlamanız önerilmez
, Windows 2000 yalnızca 7 öncelik düzeyi sağlar. Bu nedenle, iş parçacığı için önceliği doğrudan belirlemekten kaçınmaya çalışmalısınız ve programın en iyi taşınabilirliğini sağlamak için önceliği ayarlamak için MAX_ PRIORITY, MIN_ PRIORITY ve NORM PRIORITY üç statik sabiti kullanmalısınız.
Şimdi bir senaryo varsayalım. 12306 Bahar Festivali tatil sezonunda, bilet satın almak için çok fazla baskı olduğunu hepimiz biliyoruz. Bilet satan birden çok pencere var, bu da çoklu okumaya eşdeğerdir. Şimdi bu durumla karşılaşıp karşılaşmayacağınızı düşünün. Hala satılmamış son bilet varsa ve şimdi aynı anda sorgulamak için iki pencere varsa, her ikisi de son bilet olarak görüntülenir, bu da bu bileti satmak için her iki pencerenin de çalıştırılabileceği anlamına gelir ve işlem başarılı olduğunda Bundan sonra, arka uç veritabanındaki bir bilet iki kişilik ve son olarak -1'e satılır. Ya da belki aynı anda biletleri kontrol edip satıyor ve satılan miktar kalan miktara uymuyor! Elbette 12306'da bu sorun olmaz, biz sadece hayal gücüne bir örnek verelim! Bu algoritma problemini çözmek için!
Şimdi bilet satış algoritmasını yazalım!
Kalan bilet sayısını tanımlayın (12306 bilet veritabanını simüle ederek)
public class TiketAdmin { özel int tiketNum; public TiketAdmin (int tiketNum) { this.tiketNum = tiketNum; } public int getTiketNum () { dönüş tiketNum; } public void setTiketNum (int tiketNum) { this.tiketNum = tiketNum; } }Biletlemeyi başlatın, biletleri almak için iki pencereyi simüle edin
/ ** * / public class ThreadTest, Thread { //Toplam oy özel statik TiketAdmin tiketAdmin; public static void main (String args) { // Kalan oyları ilklendirin tiketAdmin = yeni TiketAdmin (100); ThreadTest threadTest1 = new ThreadTest ("Pencere 1"); threadTest1.start (); ThreadTest threadTest2 = new ThreadTest ("Pencere 2"); threadTest2.start (); } public ThreadTest (String threadName) { süper (threadName); } @Override public void run () { if (tiketAdmin.getTiketNum () > 0) { Deneyin { uyku (300 + tiketAdmin.getTiketNum ()); } catch (InterruptedException e) { e.printStackTrace (); } // Oy sayısı 0'dan büyükse bir bilet sat if (tiketAdmin.getTiketNum () > 0) { // Bilet satışlarını simüle edin tiketAdmin.setTiketNum (tiketAdmin.getTiketNum () - 1); // Kalan oyları yazdırın System.out.println (getName () + "Bir tane satıldı, kalan oylar:" + tiketAdmin.getTiketNum ()); } } } }İki iş parçacığı (iki pencere), aynı anda bilet sat, 99 bilet kaldı! Ancak bu iki bilet sattı ve bu kalan toplam oy sayısına karşılık gelmiyor. Böyle bir konu güvenli değil!
Bu mantığın büyük bir sorunu olduğunu ve oy sayısının doğru olmadığını gördük! Nasıl çözülür, böylece iş parçacığı senkronizasyonu gerçekleştirilmelidir!
Bu sorunu çözmek için, Java'nın çoklu okuma desteği, bu sorunu çözmek için bir senkronizasyon izleyicisi sunar Bir senkronizasyon izleyicisi kullanmanın genel yöntemi, kod bloklarını senkronize etmektir.
Şimdi senkronize edilmiş ekle
/ ** * * * / public class ThreadTest, Thread { //Toplam oy özel statik TiketAdmin tiketAdmin; public static void main (String args) { // Kalan oyları ilklendirin tiketAdmin = yeni TiketAdmin (100); ThreadTest threadTest1 = new ThreadTest ("Pencere 1"); threadTest1.start (); ThreadTest threadTest2 = new ThreadTest ("Pencere 2"); threadTest2.start (); } public ThreadTest (String threadName) { süper (threadName); } @Override public void run () { senkronize (tiketAdmin) { if (tiketAdmin.getTiketNum () > 0) { Deneyin { uyku (300 + tiketAdmin.getTiketNum ()); } catch (InterruptedException e) { e.printStackTrace (); } // Oy sayısı 0'dan büyükse bir bilet sat if (tiketAdmin.getTiketNum () > 0) { // Bilet satışlarını simüle edin tiketAdmin.setTiketNum (tiketAdmin.getTiketNum () - 1); // Kalan oyları yazdırın System.out.println (getName () + "Bir tane satıldı, kalan oylar:" + tiketAdmin.getTiketNum ()); } } } } }Şimdi veriler doğru! Aşağıda senkronize edilmiş olarak açıklayın!
Senkronize kod bloğuna karşılık gelen, Java'nın çok iş parçacıklı güvenlik desteği ayrıca senkronize bir yöntem sağlar Senkronize yöntem, senkronize edilmiş anahtar sözcükle bir yöntemi değiştirmektir ve bu yöntem, senkronize bir yöntem olarak adlandırılır. Eşitlenmiş değiştirilmiş örnek yöntemleri (statik olmayan yöntemler) için, bir eşitleme izleyicisini açıkça belirtmeye gerek yoktur Senkronize bir yöntemin eşitleme izleyicisi, yöntemi çağıran nesne olan budur.
İplik güvenliği aşağıdaki özelliklere sahiptir:
Herhangi bir iş parçacığı, senkronizasyon kodu bloğuna ve senkronizasyon yöntemine girmeden önce, önce senkronizasyon monitöründeki kilidi almalıdır.Senkronizasyon monitöründeki kilit ne zaman serbest bırakılacak? Program, senkronizasyon monitöründeki kilidi açıkça bırakamaz. İş parçacığı aşağıdaki gibi olacaktır. Birkaç durumda senkronizasyon monitörünün kilidini açın.
Kilit nesnesi, iş parçacığı senkronizasyonunu kontrol eder
import java.util.concurrent.locks.ReentrantLock; public class TiketAdmin { özel nihai ReentrantLock reentrantLock = new ReentrantLock (); / ** * Bilet satış operasyonu * / public void sellTiket () { reentrantLock.lock (); Deneyin { // İş parçacığı için güvenli kod sağlayın } en sonunda { reentrantLock.unlock (); } } }Lock, senkronize yöntemlere ve senkronize kod bloklarına göre daha geniş bir kilitleme işlemi yelpazesi sağlar Kilit, daha esnek bir yapıya izin verir, çok farklı özelliklere sahip olabilir ve birden çok ilgili Koşul nesnesini destekler.
Java 8, çoğu senaryoda geleneksel ReentrantReadWriteLock'un yerini alabilecek yeni bir StampedLock sınıfı türü ekler.ReentrantReadWriteLock, okuma ve yazma işlemleri için üç kilit modu sağlar: Yazma, OkumaOptimistik ve Okuma.
Kilitlenme böyledir, iki iş parçacığı birbirinin kilidi açmasını beklerken kilitlenme olur! Thread sınıfının suspend () yöntemi kolayca kilitlenmeye yol açabileceğinden, Java artık bu yöntemin İş parçacığının yürütülmesini askıya alın. Bu nedenle, çok iş parçacıklı programlamada kilitlenmeleri önlemek için önlemler alınmalıdır.
Nesne, iş parçacığı iletişimini gerçekleştirir
Bu işlevi gerçekleştirmek için, Object sınıfı tarafından sağlanan wait (), notify () ve notifyAll () yöntemlerini kullanabilirsiniz.Bu üç yöntem Thread sınıfına ait değildir, ancak Object sınıfına aittir. Ancak bu üç yöntem, aşağıdaki iki duruma bölünebilen senkronizasyon izleme nesnesi tarafından çağrılmalıdır:
Üç wait () yöntemi ile ilgili olarak, notify () ve notifyAll (), ilgili açıklamalar:
Koşul sınıfı aşağıdaki üç yöntemi sağlar:
Sistemin yeni bir iş parçacığı başlatma maliyeti nispeten yüksektir, çünkü işletim sistemiyle etkileşimi içerir. Bu durumda, iş parçacığı havuzunu kullanmak performansı artırabilir, özellikle programda kısa ömürlü çok sayıda iş parçacığı oluşturulması gerektiğinde, iş parçacığı havuzunu kullanmayı düşünmelisiniz. Veritabanı bağlantı havuzuna benzer şekilde, iş parçacığı havuzu, sistem başladığında çok sayıda boşta iş parçacığı oluşturur.Program, iş parçacığı havuzuna bir Çalıştırılabilir nesne veya Çağrılabilir nesne iletir ve iş parçacığı havuzu, çalıştırma () veya çağrılarını yürütmek için bir iş parçacığı başlatır. () yöntemi, run () veya call () yöntemi sona erdiğinde, iş parçacığı ölmez, ancak iş parçacığı havuzuna geri dönerek, bir sonraki Runnable nesnesinin run () veya call () yöntemini yürütmeyi beklerken tekrar boşta kalır. .
Java 5, iş parçacığı havuzları oluşturmak için yeni bir Yürütücü fabrika sınıfı ekledi.Fabrika sınıfı iş parçacığı havuzları oluşturmak için aşağıdaki statik fabrika yöntemlerini içerir:
İş parçacığı görevlerini gerçekleştirmek için iş parçacığı havuzunu kullanma adımları aşağıdaki gibidir:
Kod demosu:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; / ** * * * / public class ThreadPack { public static void main (String args) { // Sabit konu sayısı ExecutorService executorService = Executors.newFixedThreadPool (10); // Lambda iş parçacığı oluşturur Runnable runnable = () - > { for (int i = 0; i < 100; i ++) { System.out.println ("Konu:" + Thread.currentThread (). GetName ()); } }; // İki iş parçacığı havuzuna gönder executorService.submit (çalıştırılabilir); executorService.submit (çalıştırılabilir); // İş parçacığı havuzunu kapat executorService.shutdown (); } } Gördüğünüz gibi, alternatif uygulamaGördüğünüz gibi, alternatif uygulama
Yukarıdaki programda oluşturulmuştur Runnable Uygulama sınıfı ile başlangıçta iş parçacığı havuzunun oluşturulması arasında çok fazla fark yoktur. Runnable Sınıfın uygulanmasından sonra, program doğrudan evreler oluşturmaz ve Runnable Görev, ancak görevi gerçekleştirmek için iş parçacığı havuzu aracılığıyla!
Tamam, bugün sizinle paylaşacağım. İlgileniyorsanız, beğenmeyi ve dikkat etmeyi unutmayın!