کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش Java – تبادل اطلاعات بین thread ها یا Inter-thread communication در جاوا (synchronization و multithreading)

آموزش Java – تبادل اطلاعات بین thread ها یا Inter-thread communication در جاوا (synchronization و multithreading)

co-operation یا Inter-thread communication به امکان تبادل اطلاعات بین thread های synchronized که می خواهند به منابع یکسان دسترسی داشته باشند گفته می شود.


cooperation مکانیزیمی است که طی آن یک thread در critical section و بخش حیاتی پردازش خود متوقف شده و thread دیگری امکان وارد شدن در همان بخش و اعمال قفل را پیدا می نماید و عملیات یا پردازش بخش حیاتی خود را انجام می دهد (critical section: بخشی از کد در برنامه هایی است که در آن پردازش ها به حافظه ی اشتراکی دسترسی دارند). برای پیاده سازی این امکان می توانید از متدهای wait()، notify() و notifyAll() کلاس Object استفاده نمایید.

  • wait()
  • notify()
  • notifyAll()

متد wait()

فراخوانی این متد سبب می شود قفل اعمال (lock) شده بر روی منبع برداشته شده و thread جاری در حالت sleep قرار بگیرد و منتظر بماند تا thread دیگری متد notify() یا notifyAll() را برای این آبجکت فراخوانی کند یا منتظر بماند تا مقدار زمان مشخصی سپری شود. لازم به ذکر است که thread جاری (که در حال اجرای عملیاتی در قطعه کد synchronized می باشد) باید مالک قفل متناظر آبجکت باشد (monitor متناظر آبجکت فعلی را داشته باشد) و (wait()) منحصرا از متد synchronized فراخوانی شود، در غیر این صورت خطا رخ می دهد.

متد
شرح
public final void wait()throws InterruptedException
thread جاری را در حالت sleep برده، قفل را بر می دارد و منتظر می ماند تا thread دیگری notify() را فراخوانی نماید سپس thread قبلی فعال شود و دوباره به منبع قفل زده و به آن منبع دسترسی پیدا کند.
public final void wait(long timeout)throws InterruptedException
Thread فعلی را در حالت sleep برده و مقدار زمان مشخصی منتظر می ماند.

متد notify()

این متد یک thread متوقف شده که منتظر برداشته شدن قفل (monitor) متناظر آبجکت از روی منبع می باشد را صدا زده و سبب اجرا و ادامه ی عملیات آن می شود. اگر چندین thread منتظر برداشته شدن قفل از روی منبع هستند، تنها یکی برای بیدار شدن انتخاب می شود و می تواند به عملیات خود ادامه دهد. این انتخاب می تواند تصادفی باشد و در واقع به پیاده سازی و منطق کد مرتبط می باشد. دستور استفاده از کد به شرح زیر می باشد:

public final void notify()

متد notifyAll()

این متد تمامی thread هایی که در قفل متناظر آّبجکت (object monitor) منتظر بوده و می خواهند پس از آزاد شدن منبع به آن دسترسی پیدا کنند را صدا زده و بیدار می کند. دستور استفاده از آن به شرح زیر می باشد:

public final void notifyAll()

شرح فرایند تبادل اطلاعات و همکاری (cooperation) بین thread ها در دسترسی به منبع


آموزش Java

در زیر شرح دقیق و نکته به نکته ی نمودار بالا را مشاهده می کنید:


  1. thread ها جهت کسب lock متناظر آّبجکت وارد می شوند.
  2. یک thread موفق به کسب lock و اعمال آن بر روی منبع می شود.
  3. حال اگر توسعه دهنده متد wait() را بر روی آّبجکت مورد نظر صدا بزند، thread در حالت انتظار قرار می گیرد. در غیر این صورت lock را از روی منبع برداشته و از کد خارج می شود.
  4. اگر توسعه دهنده notify() یا notifyAll() را فراخوانی کند، thread وارد وضعیت runnable شده و آماده است که عملیات را ادامه دهد.
  5. اکنون thread می تواند قفل (lock) را کسب کرده و بر روی منبع اعمال کند.
  6. پس از اینکه عملیات به پایان رسید، thread قفل را برداشته و از وضعیت monitor آبجکت خارج می شود.

چرا متدهای wait()، notify() و notifyAll() بجای کلاس Thread در سطح کلاس Object تعریف شده اند؟

در جاوا هر object ای یک lock متناظر دارد. از آنجایی که این متد ها با lock کار می کنند و فقط object دارای lock می باشد، متدهای wait()، notify() و notifyAll() در سطح کلاس آبجکت تعریف شده اند.

شرح تفاوت بین متدهای wait و sleep


No.
wait()
sleep()
1
فراخوانی متد wait() سبب می شود قفل از روی منبع برداشته شود.
متد sleep() قفل یا lock را از روی منبع برنمی دارد.
2
wait() در سطح کلاس Object تعریف شده است.
متد sleep() در کلاس Thread تعریف شده است.
3
یک متد non-static می باشد.
یک متد static است.
4
وقتی آّبجکت به سبب فراخوانی متد wait() در وضعیت انتظار قرار می گیرد، متد notify() یا notifyAll() باید آن را صدا زده و مطلع کنند.
پس از اینکه مدت زمان مشخص سپری شد، وضعیت sleep خاتمه می یابد.

مثال کاربردی از inter-thread communication و همکاری بین thread ها در Java


class Customer{  
int amount=10000;  
synchronized void withdraw(int amount){  
System.out.println("going to withdraw...");  
if(this.amount< amount){ System.out.println("Less balance; waiting for deposit...");
                        try{wait();}catch(Exception e){}
                        }
                        this.amount-=amount;
                        System.out.println("withdraw completed...");
                        }
                        synchronized void deposit(int amount){
                        System.out.println("going to deposit...");
                        this.amount+=amount;
                        System.out.println("deposit completed... ");
                        notify();
                        }
                        }
                        class Test{
                        public static void main(String args[]){
                        final Customer c=new Customer();
                        new Thread(){
                        public void run(){c.withdraw(15000);}
                        }.start();
                        new Thread(){
                        public void run(){c.deposit(10000);}
                        }.start();
                        }}

خروجی:

going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
1396/08/21 3586 1199
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...