0 امتیاز
قبل در برنامه نویسی توسط (242 امتیاز)
برچسب گذاری دوباره قبل توسط

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

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 پاسخ

+3 امتیاز
قبل توسط (426 امتیاز)
انتخاب شده قبل توسط
 
بهترین پاسخ

ببین یه وقفه زمانی باعث شده که شما فکر کنی که 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 امتیاز
1 پاسخ 395 بازدید
سوال شده 9 سال قبل در برنامه نویسی توسط tashtboland (2.2هزار امتیاز)
0 امتیاز
1 پاسخ 512 بازدید
0 امتیاز
0 پاسخ 347 بازدید
0 امتیاز
2 پاسخ 935 بازدید
+1 امتیاز
1 پاسخ 394 بازدید
0 امتیاز
1 پاسخ 450 بازدید
0 امتیاز
2 پاسخ 332 بازدید
0 امتیاز
0 پاسخ 270 بازدید
...