Programcı: İş parçacığını nasıl doğru bir şekilde durduracağınızı hala bilmiyor musunuz?

Önsöz

İleti dizileri genellikle arka plan geliştirmede kullanılır, bu nedenle ileti dizisini her kapattığınızda düzeliyor musunuz?

Özellikle, programcıların daha fazla sorun yaşamasına neden olan çok iş parçacıklı geliştirme senaryoları giderek artmaktadır. .

Bugün ipliği nasıl doğru bir şekilde durduracağımıza geldik. . .

İplik nasıl doğru şekilde durdurulur?

  • Bir iş parçacığı genellikle görev yürütmenin sonuna kadar normal olarak çalışır. O halde ipliği ne zaman durdurmamız gerekiyor? Örneğin, kullanıcı davranışının iptal etme eylemi, çalışma zaman aşımı veya çalışan işlemdeki bir hata da mevcut iş parçacığını durdurmalı, uygulamanın yeniden başlatılması gerekiyor, vb. Çalışan iş parçacığını aktif olarak durdurmamız gerekiyor. İş parçacığını güvenli ve güvenilir bir şekilde nasıl durduracağımız basit bir mesele değil Bir şeyler.
  • Java dili, bir iş parçacığını güvenli ve güvenilir bir şekilde durduracak bir mekanizmaya sahip değildir, ancak o anda çalışan iş parçacığını bildirmek için bir iş parçacığı başlatmak için bir kesme mekanizması sağlar, onu çalıştırmadığınızı söyler, durdurabilirsiniz. Güçlüyü durdurmaktansa.
  • Kesintinin kesinti anlamına geldiğini hepimiz biliyoruz.Son karar hala bildirilen konu başlığında. Ruh haline bağlı olarak durdurulabilir veya durdurulamaz. Eğer durmazsa ne yapabiliriz? Çekişiyor mu?
  • Bunu görünce, merak eden pek çok insan olmalı, iş parçacığını durdurmak için bir mekanizma olarak neden programın geliştiricileriyiz? Aşağıdaki şekildeki sahneye ve açıklamaya bakıyoruz ve çok net.

Java dili tasarımı iş parçacığının doğru durmasını sağlar ve durdurulan iş parçacığının kendisine adım atar. Durdurulan iş parçacığı ne zaman duracağını bilir.

Zorla durdurmak yerine bildirim için kesinti kullanın

Doğru kesme kullanımı

Normal koşullar altında
  • Aşağıdaki kodda gösterildiği gibi:
public class MyNormalInterruptDemo { public static void main (String args) { Thread thread = new Thread (yeni MyNormalInterrupt ()); thread.start (); // Yürütmeden sonra, işlemeyi kes thread.interrupt (); } } class MyNormalInterrupt Runnable { @Override public void run () { System.out.println ("İş parçacığı yürütülmeye başladı"); int i = 0; süre (ben < Tamsayı.MAX_VALUE) { i ++; } System.out.println ("Nihai yürütme sonucu:" + i); } }

Konsol çıkışı

Konu başladı

Nihai yürütme sonucu: 2147483647

Sonuçlardan, son program hala normal şekilde yürütülüyor.Açan tarafta kesme işlemini gerçekleştirmemize rağmen, iş parçacığı yürütme gövdesindeki kesme işlemini işlemedik.Çağrı yapan taraf bir kesme sinyali verse bile, iş parçacığı yürütme gövdemiz Boşver. Daha sonra, işlemin iş parçacığı gövdesinde nasıl kesileceğine bakalım.

public class MyNormalInterruptDemo { public static void main (String args) InterruptedException {atar Thread thread = new Thread (yeni MyNormalInterrupt ()); thread.start (); // Yürütmeden sonra, işlemeyi kes Thread.sleep (1000); thread.interrupt (); } } class MyNormalInterrupt Runnable { @Override public void run () { System.out.println ("İş parçacığı yürütülmeye başladı"); int i = 0; süre (ben < Tamsayı.MAX_VALUE! Thread.currentThread (). İsInterrupted ()) { i ++; } System.out.println ("Nihai yürütme sonucu:" + i); } }

Konsol

Konu başladı

Nihai yürütme sonucu: 1103717170

Açıktır ki, nihai yürütme sonucu 2147483647 olduğu için program çalıştırılmamıştır. Döngü durumunda, iş parçacığının kesilip kesilmediğine ve iş parçacığının nasıl kesildiğine, döngü sona erdiğine ve iş parçacığının yürütülmesine ilişkin bir koşul eklenir.

Konu engelleme

kod aşağıdaki gibi gösterilir:

public class MySleepInterruptDemo { public static void main (String args) InterruptedException {atar Thread thread = new Thread (yeni MySleepInterrupt ()); thread.start (); // Yürütmeden sonra, işlemeyi kes Thread.sleep (100); thread.interrupt (); } } class MySleepInterrupt Runnable { @Override public void run () { System.out.println ("İş parçacığı yürütülmeye başladı"); Deneyin { int i = 0; süre (ben < Tamsayı.MAX_VALUE! Thread.currentThread (). İsInterrupted ()) { i ++; } Thread.sleep (1000L); System.out.println ("Nihai yürütme sonucu:" + i); } catch (InterruptedException e) { e.printStackTrace (); } } }

Konsol

Konu başladı

java.lang.InterruptedException: uyku kesildi

java.lang.Thread.sleep (Yerel Yöntem)

com.karl.concurrent.chapter07.MySleepInterrupt.run (MySleepInterruptDemo.java:28) adresinde

java.lang.Thread.run'da (Thread.java:748)

Run yönteminde uyku yöntemi yürütüldüğünde, InterruptedException istisnası alması istenir

Bir iş parçacığı uyurken bir kesme sinyali aldığında, yanıt vermenin yolu bir InterruptedException oluşturmaktır.

İş parçacığı yineleme engelleme

Kod aşağıdaki gibidir:

public class MyEveryLoopSleepInterruptDemo { public static void main (String args) InterruptedException {atar Thread thread = new Thread (yeni MyEveryLoopSleepInterrupt ()); thread.start (); // Yürütmeden sonra, işlemeyi kes Thread.sleep (100); thread.interrupt (); } } class MyEveryLoopSleepInterrupt Runnable { @Override public void run () { System.out.println ("İş parçacığı yürütülmeye başladı"); Deneyin { int i = 0; süre (ben < Tamsayı.MAX_VALUE! Thread.currentThread (). İsInterrupted ()) { i ++; Thread.sleep (10L); } System.out.println ("Nihai yürütme sonucu:" + i); } catch (InterruptedException e) { e.printStackTrace (); } } }

Konsol

Konu başladı

java.lang.InterruptedException: uyku kesildi

java.lang.Thread.sleep (Yerel Yöntem)

com.karl.concurrent.chapter07.MyEveryLoopSleepInterrupt.run (MyEveryLoopSleepInterruptDemo.java:29)

java.lang.Thread.run'da (Thread.java:748)

Yukarıdaki kod ile iş parçacığı engelleme arasındaki farkı gözlemleyin

  • Dolaşımda engellendi
  • İpliğin döngü durumunda kesintiye uğrayıp uğramadığına karar vermeyin

Nedeni: İş parçacığının yürütme gövdesinde, çoğu zaman iş parçacığı uyku durumunda olduğundan ve kesilen iş parçacığı bir InterruptedException istisnası atar.Bu zamanda, döngü koşulunun yargısı aslında gereksizdir. Bu nedenle, her döngüde kesintiye uğrayıp uğramadığını kontrol etmeye gerek yoktur. Çünkü döngü içinde uyumak, bu kesintiye cevap vermemize yardımcı olacaktır.

Hatalı kesinti kullanımı

Eğer try catch kullanılırsa, kesme geçersiz olacaktır. Kod aşağıdaki gibidir:

public class MyErrorInterruptDemo { public static void main (String args) InterruptedException {atar Thread thread = new Thread (yeni MyErrorInterrup ()); thread.start (); // Yürütmeden sonra, işlemeyi kes Thread.sleep (100); thread.interrupt (); } } class MyErrorInterrup, Runnable { @Override public void run () { System.out.println ("İş parçacığı yürütülmeye başladı"); int i = 0; süre (ben < Tamsayı.MAX_VALUE! Thread.currentThread (). İsInterrupted ()) { i ++; Deneyin { Thread.sleep (10L); } catch (InterruptedException e) { e.printStackTrace (); } } System.out.println ("Nihai yürütme sonucu:" + i); } }

Konsol

İş parçacığı neden sürekli çalışıyor?

  • Kısa süre sonra birçok arkadaş, döngü gövdesi istisnayı yakaladığı ve onu fırlatmadığı için bunun yürütüldüğünü düşündü.
  • Öyleyse neden iş parçacığının hala çalışıp çalışmadığını belirlemek için döngü koşulunu ekliyoruz? İkinci soruyla karşı karşıya kalan arkadaşlar cevap veremeyebilir.

Şöyle nedenleri vardır:

Çünkü Java, Uyku yöntemi mekanizmasını ayarladığında, kesme yanıtlandığında, iş parçacığının kesme bayrağı açıktır, çünkü kesmeye yanıt verdiğimizde, yargılama koşulu gerçekten başarısız olduğu için iş parçacığının kesme bayrağı bitini kullanmaya devam ederiz. Bunu görünce, aniden farkına varan birçok arkadaş olmalı.

Gerçek iş geliştirmede son uygulama

  • Kesinti ilkesini daha iyi anlamamıza yardımcı olmak için, yukarıdaki basit durumlar gerçek geliştirme sürecimizdeki yürütme iş parçacığının nasıl düzgün şekilde kesileceğini açıklayacaktır.

İlk tür: aktarım kesintisi (önerilir)

  • İlk hata gösterimine bakın
public class RightWayStopThreadInProd { public static void main (String args) InterruptedException {atar Thread thread = new Thread (yeni MyRightWayStopThreadInProd ()); thread.start (); Thread.sleep (100); thread.interrupt (); } } class MyRightWayStopThreadInProd Runnable { @Override public void run () { System.out.println ("İşin yürütülmesini başlat"); while (true) { // Yürütme sırasında diğer yöntemleri çağırmayı simüle edin Bu method(); } } özel boşluk yöntemi () { Deneyin { Thread.sleep (1000); } catch (InterruptedException e) { e.printStackTrace (); } } }

Konsol

Yukarıdaki kodun temel problemi herkesin açık olması gerektiğini düşünüyorum .. method () metodunu çağırma sürecinde uçbirim yanıtı denendiği / yakalandığı için run metodu algılanamıyor. Böylece iş parçacığı her zaman çalışıyor.

Bu nedenle, asıl sorun yöntem yönteminde yatmaktadır.Kesme yanıtı çalıştırma yöntemine kusulamaz Yöntem yöntemi, kesme istisnasını kendi başına çözemese bile, doğru yaklaşım rapor edilmelidir.Yüksek seviye (çağrı yöntemi yöntemi) duruma göre halleder. Özel olarak çözülmedi.

Doğru kod şuna benzer:

public class RightWayStopThreadInProd { public static void main (String args) InterruptedException {atar Thread thread = new Thread (yeni MyRightWayStopThreadInProd ()); thread.start (); Thread.sleep (100); thread.interrupt (); } } class MyRightWayStopThreadInProd Runnable { @Override public void run () { System.out.println ("İşin yürütülmesini başlat"); while (true) { // Yürütme sırasında diğer yöntemleri çağırmayı simüle edin Deneyin { Bu method(); } catch (InterruptedException e) { // Çalıştırma yönteminde hata oluşturamayacağınız için, burada yapabileceğimiz şey günlüğü kaydetmek veya programın çalışmasını durdurmaktır. System.out.println ("Günlüğü kaydet / çalışmakta olan programı durdur"); e.printStackTrace (); } } } private void yöntemi () InterruptedException {atar Thread.sleep (1000); } }

Devam ettirme kesintiye uğradı

Bir kesinti göndermek istemediğimizde veya kesintiye uğratamadığımızda, kesinti işlemeye devam edebiliriz.

Catch deyiminde, sonraki yürütmede bir kesinti olup olmadığını kontrol etmek için, kesmeyi sürdürmek için Thread.currentThread (). İnterrupt () öğesini çağırın. Kusmanın ve sözünü kesmenin anlamının yukarıdaki açıklamasıdır.

Spesifik kod aşağıdaki gibidir

public class RightWayStopThreadInProd2 { public static void main (String args) InterruptedException {atar Thread thread = new Thread (yeni MyRightWayStopThreadInProd ()); thread.start (); Thread.sleep (2000); thread.interrupt (); } } class MyRightWayStopThreadInProd2 Runnable { @Override public void run () { System.out.println ("İşin yürütülmesini başlat"); while (true) { eğer (Thread.currentThread (). isInterrupted ()) { System.out.println ("Bir kesinti oluştu, yürütmeden çık"); kırmak; } // Yürütme sırasında diğer yöntemleri çağırmayı simüle edin Bu method(); } } özel boşluk yöntemi () { Deneyin { Thread.sleep (4000); } catch (InterruptedException e) { Thread.currentThread (). İnterrupt (); e.printStackTrace (); } } }

Konsol

İşe başla

java.lang.InterruptedException: uyku kesildi

java.lang.Thread.sleep (Yerel Yöntem)

com.karl.concurrent.chapter07.MyRightWayStopThreadInProd.method (RightWayStopThreadInProd.java:35)

com.karl.concurrent.chapter07.MyRightWayStopThreadInProd.run (RightWayStopThreadInProd.java:29)

java.lang.Thread.run'da (Thread.java:748)

Bir kesinti meydana geldi, yürütmeden çık

Şu anda, her döngüde üst katmanda bir kesinti olup olmadığına karar vermemiz gerekiyor.

Kesintilere yanıt vermenin diğer yolları

Yukarıda iş parçacığı engellemenin yanıt kesintisini açıklıyoruz, benzer şekilde aşağıdaki gibi başka yöntemler de var:

  • Nesne: bekle ()
  • Konu: birleştirmek ()
  • BlockingQueue: take () / put ()
  • Kilitleme: Kilitleme Kesintisiz ()
  • CountDownLatch: await ()
  • CyclicBarrier: await ()
  • Bekle

sonuç olarak

Bunu görünce, herkesin iş parçacığı kesintisi konusunda belirli bir anlayışa sahip olduğuna inanıyorum. Sınırlı yeteneklerim ve ifadelerim var ve bunları zamanında düzeltmeyi umuyorum.

Programcı: Çok iş parçacıklı paylaşılan kaynak senkronizasyonu, dikkatli bakmazsanız pişman olacaksınız
önceki
İyi makale paylaşımı: JavaWeb'de size yönetici oturum açma bilgilerini ve CURD bilgilerini göstermek için 5 resim
Sonraki
Programcı: Nesnenin özünü ortaya çıkarmak için Java'nın 5 özelliği
Çin'in bilim ve teknolojisinin bir başka güzel haberi daha var, kuantum çip teknolojik sınırı aşıyor ve dünya hemen köşede!
Maskeyi litografi makinesi ile değiştirin! Hollanda kontrolden çıktı ve yardım istiyor, Rusya: Çin'in büyük bir fırsatı var
Uyarılmış! Çin bağımsız olarak gelecekte artık kısıtlanmayacak bir "kuantum çipi" geliştirdi
14nm işleminin seri üretiminin ardından, Çin'in çipi 6nm'lik buz darboğazını kırarak başka bir iyi habere sahip
inanılmaz! Çok az yerli litografi makinesi üreticisi var ve bu görünmez dev bize umut veriyor.
Çin Bilimler Akademisi başka bir büyük atılım yaptı! Batılı ülkeler buna inanamıyor, Çin bunu nasıl yaptı?
Du Yuesheng, karısının "raydan çıktığını" ve idarenin basit ve zorba olduğunu ve bir Şangay kahramanı olmayı hak ettiğini buldu.
Programcı: Altta yatan bilgisayar analiziyle birleştirilmiş "İplik Güvenliği İlkelerinin Analizi"
Programcı: Basit tutun, Class dosyasının JVM'ye nasıl yüklendiğini tam olarak anlamanıza izin verin
Lojistik şirketleri kapanmıyor, devlet şirketleri hastalıkla savaşmak için el ele veriyor
Wuhan'a sür! Lanmei Havayolları ücretsiz salgın önleme malzemeleri taşıma sözü verdi
To Top