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

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

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

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 خارج نمیشه. اما اگر داخل حلقه چیزی در خروجی چاپ شود، برنامه درست کار می‌کند. مشکل از کجاست؟

سوال 2 هفته قبل در تالار برنامه نویسی توسط 1993 (104 امتیاز)
برچسب گذاری مجدد در 2 هفته قبل توسط 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 تویه روند اجرا یک کاره سنگینه که باعث بلاک شدن روند اجرا میشه که نتیجش بروز این رفتارهاس.

 

موفق باشی

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

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

0 رأی
1 جواب میانگین بازدید روزانه 0.1497 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.1188 بازدید
سوال 4 سال قبل در تالار برنامه نویسی توسط tashtboland (2,201 امتیاز)
+1 رأی
1 جواب میانگین بازدید روزانه 0.16369 بازدید
0 رأی
1 جواب میانگین بازدید روزانه 0.13240 بازدید
0 رأی
0 جواب میانگین بازدید روزانه 0.09135 بازدید
0 رأی
2 جواب میانگین بازدید روزانه 0.26515 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.5944 بازدید
0 رأی
1 جواب میانگین بازدید روزانه 0.16275 بازدید
0 رأی
2 جواب میانگین بازدید روزانه 0.06134 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.19107 بازدید
کانال تلگرام جواب یاب
...