{CodeGate}

synchronized در جاوا (MultiThreading in Java)

در این آموزش  تیم کدگیت را با ادامه thread در جاوا را همراهی کنید.  در جلسه پیش در مورد نحوه ایجاد thread صحبت شد. این بار میخواهیم در مورد synchronized در جاوا صحبت کنیم پس پیش نیاز این آموزش جلسه اول thread در جاوا است.

مشکل Thread

قبل از اینکه درباره synchronized در جاوا صحبت کنیم به مشکل thread میپردازیم. وقتی ما دو یا چند Thread را همزمان اجرا می کنیم ممکن است وضعیتی پیش بیاید که چند Thread همزمان تلاش به دسترسی به یک منبع را بکنند و نتیجه پیش بینی نشده ای به وجود بیاید برای مثال وقتی چند Thread همزمان بخواهند در یک فایل بخصوصی اطلاعات بنویسند. این کار باعث میشود اطلاعات ما به صورت خراب در فایل ذخیره شود.

بگذارید یک مثال ساده بزنم و شما بیشتر با مشکل گفته شده آشنا شوید. ما یک برنامه ساده می نویسیم به این صورت که دو thread اجرا شده و هر دو یک متد را صدا بزنند. نام متد increment است و یک متغیر را با یک جمع میکند. متغیر ما یک فیلد است به نام count کد برنامه به شکل زیر است.

به صورت خلاصه کد بالا شامل

  1. RunThreads : متدی که دو thread ما را می سازد.
  2. Count : شمارنده ما
  3. Run : متد که در thread است و 10000 بار شمارنده count را با یک جمع می کند.
  4. Start: متدی که thread ما را آغاز می کند.
  5. Join: متدی که منتظر می ماند thread مورد نظر تمام شود سپس برنامه را ادامه می دهد.
  6. Increment: متدی که شمارنده ما را با یک جمع میکند.
  7. Main: نیاز به توضیح نداره!!!!!!

در نتیجه برنامه ما باید خروجی count را چاپ کند. طبق توضیحاتی داده شد هر thread  برابر با 10000 بار شمارنده را با یک جمع می کنند و ما دو thread داریم پس باید 20000 شود شمارنده ما بعد از اتمام thread. ولی خروجی برنامه به صورت زیر است:

thread-problem-output

همانطور که میبینید خروجی آن چیزی نیست که ما میخواهیم. دلیل این است که وقتی ما شمارنده با یک جمع میکنیم کامپیوتر چندین مرحله میگذرد تا این عمل انجام دهد و اگر قبل از این مراحل thread دیگری وارد شود شمارنده را مقدار قبلی میبیند و بعد جمع ما به جای این که دوبار انجام شده باشد انگار یک بار انجام شده است.  در تصویر زیر همانطور که میبینید 2 thread همزمان increment را صدا زدند وقتی اولین thread در حال تغییر count است(count هنوز تغییر نکرده) در همان موقع thread دوم وارد شده و وقتی میخواهد count را جمع کند آن  را 10 میبیند(چون هنوز تغییر نکرده توسط thread اول) به جای 11.

synchronized در جاوا

synchronized در جاوا

یک راه حل ساده برای مشکل گفته شده دارد آن هم استفاده از synchronized در جاوا است. Synchorized یک بلاک است که ما آن قسمت از   Threadها که اشتراک دارند درون آن قرارمی دهیم. synchronized در جاوا یک object به عنوان lock میگیرد که در آموزش های بعدی به آن پرداخته خواهد شد و در این آموزش جای آن this قرار می دهیم.در زیر کد بالا که مشکل داشت را با synchronized در جاوا نوشتیم.

خروجی کد بالا طبق انتظار ما باید 20000 بدهد و همینطور هم هست.

synchronized در جاوا

کاری که synchronized در جاوا انجام میدهد این است که اجازه نمیدهد بیشتر از یک thread وارد بلاکش شود و این کار را با lock کردن بلاک خود انجام می دهد. وقتی thread بخواهد وارد بلاک بشود اول چک میشود که آیا lock هست بلاک یا نه. اگر lock بود منتظر میماند تا بلاک از حالت lock خارج شود.همانطور که در تصویر زیر میبینید thread دوم منتظر میماند thread اول از بلاک خارج شود.

synchorized-diagram2

پسورد: www.codegate.ir

 

دسته : java, جاوا, همزمانی در جاوا (MultiThreading)

دیدگاه بگذارید

نظر شما چیست؟

مطلع کردن شما از
avatar

wpDiscuz