مدیریت ترد ها


از بین بردن تردها در جاوا

از بین بردن ترد ها در جاوا

یک ترد به شکل خودکار با اجرای کامل متد run() از بین می رود. اما ممکن است به اقتضای برنامه نیاز باشد متوقف شده یا از بین برود. برای چنین منظوری قبل تر از متدهای suspend()، resume() و stop() استفاده می شد. اما این متدها به خاطر مشکلاتی که ایجاد می کردند منسوخ شدند. روش های بهتر برای توقف یا جلوگیری از اجرای یک ترد استفاده از یک متغیر Boolean یا متد Thread.interrupt() است.

  • استفاده از یک متغیر Boolean

به سادگی مقدار این متغیر را در زمان لازم برای خروج به true تغییر می دهیم.

class MyThread implements Runnable { 
  
    // to stop the thread 
    private boolean exit; 
  
    private String name; 
    Thread t; 
  
    MyThread(String threadname) 
    { 
        name = threadname; 
        t = new Thread(this, name); 
        System.out.println("New thread: " + t); 
        exit = false; 
        t.start(); // Starting the thread 
    } 
  
    // execution of thread starts from run() method 
    public void run() 
    { 
        int i = 0; 
        while (!exit) { 
            System.out.println(name + ": " + i); 
            i++; 
            try { 
                Thread.sleep(100); 
            } 
            catch (InterruptedException e) { 
                System.out.println("Caught:" + e); 
            } 
        } 
        System.out.println(name + " Stopped."); 
    } 
  
    // for stopping the thread 
    public void stop() 
    { 
        exit = true; 
    } 
} 
  
// Main class 
public class Main { 
    public static void main(String args[]) 
    { 
        // creating two objects t1 & t2 of MyThread 
        MyThread t1 = new MyThread("First  thread"); 
        MyThread t2 = new MyThread("Second thread"); 
        try { 
            Thread.sleep(500); 
            t1.stop(); // stopping thread t1 
            t2.stop(); // stopping thread t2 
            Thread.sleep(500); 
        } 
        catch (InterruptedException e) { 
            System.out.println("Caught:" + e); 
        } 
        System.out.println("Exiting the main Thread"); 
    } 
} 

خروجی :

New thread: Thread[First  thread, 5, main]

New thread: Thread[Second thread, 5, main]

First  thread: 0

Second thread: 0

First  thread: 1

Second thread: 1

First  thread: 2

Second thread: 2

First  thread: 3

Second thread: 3

First  thread: 4

Second thread: 4

First  thread: 5

Second thread Stopped.

First  thread Stopped.

Exiting the main Thread

 

به کمک این روش بسیار ساده هر زمان که لازم باشد می توانیم ترد را متوقف کنیم و هم چنین از خطاهای نوع run-time نیز جلوگیری کنیم.

  • استفاده از متغیر volatile Boolean

برای استفاده امن و اصولی از تردها می توان از چنین متغیری استفاده نمود. یک متغیر volatile بطور مستقیم در حافظه مختص به اسکوپ main نگهداری می شود. چنین مزیتی زمانی کارآمد است که چندین ترد در حال انجام کار باشند. و همگی به این متغیر دسترسی داشته باشند و فرض کنید هر کدام جداگانه مقدای که خود لازم دارند را در این متغیر بریزند و تردهای دیگر از آخرین مقدار این متغیر مطلع خواهند شد.

public class Main { 
  
    // static used here 
    // because a non-static variable 
    // cannot be referenced 
    // from a static context 
  
    // exit variable to stop both 
    // the main and inside threads 
    static boolean exit = false; 
  
    public static void main(String[] args) 
    { 
        System.out.println("started main thread.."); 
  
        // a thread inside main thread 
        new Thread() { 
            public void run() 
            { 
                System.out.println("started inside thread.."); 
  
                // inside thread caches the value of exit, 
                // so changes made to exit are not visible here 
                while (!exit) // will run infinitely 
                { 
                } 
  
                // this will not be printed. 
                System.out.println("exiting inside thread.."); 
            } 
        }.start(); 
  
        try { 
            Thread.sleep(500); 
        } 
        catch (InterruptedException e) { 
            System.out.println("Caught :" + e); 
        } 
  
        // so that we can stop the threads 
        exit = true; 
        System.out.println("exiting main thread.."); 
    } 
} 

با اجرای این برنامه خطایی از جنس Runtime Error برنامه را بلاک خواهد کرد. چراکه بواسطه تعریف متغیری که همه به طور یکسان و دلخواه به آن دسترسی دارند، یک حلقه بی نهایت در برنامه ساخته ایم. پیام این خطا عبارت Time Limit Exceeded می باشد.خروجی برنامه بالا نشان می دهد که ترد inside هرگز متوقف نمی شود. زیرا تغییری که در مقدار متغیر ‘exit’ در ترد main ایجاد شده، توسط ترد inside مشاهده نمی شود. برای جلوگیری از این مشکل از متغیر volatile استفاده می کنیم. مثل قطعه کد زیر :

public class Main { 
  
    // static used here because 
    // a non-static variable cannot be referenced 
    // from a static context 
  
    // exit variable to stop both 
    // the main and inside threads 
    static volatile boolean exit = false; 
    public static void main(String[] args) 
    { 
  
        System.out.println("started main thread.."); 
  
        // a thread inside main thread 
        new Thread() { 
            public void run() 
            { 
  
                // changes made to exit 
                // in main thread are visible here 
                System.out.println("started inside thread.."); 
  
                // will not run infinitely 
                while (!exit) { 
                } 
  
                // this will be printed 
                System.out.println("exiting inside thread.."); 
            } 
        }.start(); 
  
        try { 
            Thread.sleep(500); 
        } 
        catch (InterruptedException e) { 
            System.out.println("Caught :" + e); 
        } 
  
        // so that we can stop the threads 
        exit = true; 
        System.out.println("exiting main thread.."); 
    } 
} 

خروجی این برنامه :started main thread..started inside thread..exiting main thread..exiting inside thread..

 

همان طور که مشاهده می کنید دیگر در یک حلقه بی نهایت نمی افتیم. زیرا متغیر volatile درون حافظه main نگهداری می شود و هر ترد می تواند از آخرین مقدار این متغیر به درستی مطلع گردد. در نهایت در حالتی امن و صحیح می توانیم تردهای برنامه را کنترل نماییم.

  • استفاده از متد interrupt

این متد در هر زمانی که صدا زده شود کار ترد مربوطه را متوقف می نماید.

class MyThread implements Runnable { 
  
    Thread t; 
  
    MyThread() 
    { 
        t = new Thread(this); 
        System.out.println("New thread: " + t); 
        t.start(); // Starting the thread 
    } 
  
    // execution of thread starts from run() method 
    public void run() 
    { 
        while (!Thread.interrupted()) { 
            System.out.println("Thread is running"); 
        } 
        System.out.println("Thread has stopped."); 
    } 
} 
  
// Main class 
public class Main { 
    public static void main(String args[]) 
    { 
        // creating objects t1 of MyThread 
        MyThread t1 = new MyThread(); 
  
        try { 
            Thread.sleep(1); 
  
            // t1 is an object of MyThread 
            // which has an object t 
            // which is of type Thread 
            t1.t.interrupt(); 
  
            Thread.sleep(5); 
        } 
        catch (InterruptedException e) { 
            System.out.println("Caught:" + e); 
        } 
        System.out.println("Exiting the main Thread"); 
    } 
} 

 

به این پست امتیاز دهید

روی ستاره های کلیک کنید و امتیاز بدید

میانگین امتیاز 0 / 5. تعداد: 0

از امتیاز شما متشکریم

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

Enter Captcha Here : *

Reload Image