تمام نشدن حلقه while در جاوا

0 رأی
میانگین بازدید روزانه 1.0866 بازدید

لطفا به کد زیر توجه کنید

public class PortfolioVolatile extends Thread {

  private volatile Thread stopMe;

  public PortfolioVolatile(String name) {
    super(name);
  }

  public void stopMe() {
    this.stopMe = null;
  }

  @Override
  public void run() {
    this.stopMe = Thread.currentThread();

    while (stopMe == Thread.currentThread()) {
      System.out.println(Color.ANSI_GREEN + "The Portfolio thread is running");
    }
    System.out.println(Color.ANSI_RED + "The Portfolio thread was killed");
  }
}

و این هم کلاس اصلی

public class KillTheThread {

  public static void main(String[] args) {
    var port = new PortfolioVolatile("Portfolio data");
    port.start();

    int i = 0;
    while (i < 5) {
      i++;
//      System.out.println(i);
    }
    port.stopMe();
  }
}

همانطور که مشاهده می‌کنید، مقداری که قرار است در خروجی در حلقه چاپ شود را کامنت کرده‌ام. که اگر برنامه فوق را اجرا کنیم، هیچ وقت از حلقه while خارج نمیشه. اما اگر داخل حلقه چیزی در خروجی چاپ شود، برنامه درست کار می‌کند. مشکل از کجاست؟

سوال 1 ماه قبل در تالار برنامه نویسی توسط 1993 (111 امتیاز)
برچسب گذاری مجدد در 1 ماه قبل توسط Saeed Zarinfam

1 جواب

+3 رأی
 
بهترین جواب

ببین یه وقفه زمانی باعث شده که شما فکر کنی که Thread داره بازی در میاره که در اصل این ذات Thread است. ولی یعنی چی

اگر اون خط کامنت شده رو از Comment در بیاری Main Thread درگیر یک I/O کوچلو برای چاپ کردن مقدار i میشه. از اون طرف Thread مربوط به port هم رفته مقدار دهی شده یعنی

this.stopMe = Thread.currentThread();

رو انجام داده و یک دور اون حلقه while داخل run اجرا میشه

از این طرف Main Thread رسیده به

 port.stopMe();

 

پس مقدار stopme رو برابر با null میذاره

از اون طرف Thread مربوط به port که میخواد دوباره حلقه رو اجرا کنه به گیر میخوره یعنی شرط while دیگه true نیست پس از حلقه بیرون میاد و اون پیغام was killed ..... رو اجرا میکنه و برنامه تمومه.

 

ولی اما اگر اون خط comment بمونه Main Thread سریع حلقه رو اجرا میکنه و سریع به

port.stopMe();

میرسه درحالی که روند اجرا اون Thread هنوز متد run اون Thread رو اجرا نکرده و هنوز مقدار stopMe = null است  باز این متد میاد دوباره مقدار stopMe رو برابر با null میزاره یعنی اجرا شده این ()port.stopme  بیهوده اس

پس وقتی که متد run اجرا میشه دیگه جای نیست که اونو متوقف کنه پس اون حلقه داخلش یک شرط همیشه درسته و تا بینهایت اون پیام رو چاپ میکنه

نکته : I/O تویه روند اجرا یک کاره سنگینه که باعث بلاک شدن روند اجرا میشه که نتیجش بروز این رفتارهاس.

 

موفق باشی

جواب 1 ماه قبل توسط یوری (426 امتیاز)
انتخاب شده در 1 ماه قبل توسط 1993

سوال های مشابه

0 رأی
1 جواب میانگین بازدید روزانه 0.14102 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.1193 بازدید
سوال 5 سال قبل در تالار برنامه نویسی توسط tashtboland (2,201 امتیاز)
+1 رأی
1 جواب میانگین بازدید روزانه 0.16376 بازدید
0 رأی
1 جواب میانگین بازدید روزانه 0.13246 بازدید
0 رأی
0 جواب میانگین بازدید روزانه 0.09142 بازدید
0 رأی
2 جواب میانگین بازدید روزانه 0.26524 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.4857 بازدید
0 رأی
1 جواب میانگین بازدید روزانه 0.16281 بازدید
0 رأی
2 جواب میانگین بازدید روزانه 0.06138 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.18113 بازدید
کانال تلگرام جواب یاب
...