Parsa Mihandoost
Parsa Mihandoost
خواندن ۲ دقیقه·۴ سال پیش

کلاس خود را زندانی کنید تا Thread safe شود! (جاوا)


یکی از مشکلات و دردسرهای برنامه‌نویس‌های جاوا که سمت وب کار میکنن Thread safe بودن کلاس‌هاشون هست. میدونیم که Web container های جاوا مثل tomcat برای جواب دادن به درخواست‌ها از thread استفاده میکنند و هر درخواست در thread جدا پاسخ داده میشود بنابراین محیط کار ما multi-thread هست و باید حواسمون به shared-resource هامون باشه.

امروز ساده‌ترین راه برای Thread-safe بودن رو بررسی میکنیم که میگه : اگر میخوای کلاست مشکل همروندی نداشته باشه و متغیرهات توسط تردهای دیگه دست‌کاری نشن بیا و همه متغیرهای سطح کلاست رو پاک کن و اونها رو در متد تعریف کن! بکارگیری این روش خیلی سادس مثلا مثال زیر :

public class SafeClass{ public void a(){ int a=1; Object a=new Object() // do something } }

حالا اگر صدتا thread هم روی یک آبجکت متد a رو صدا بزنند هرکدوم متغیرهای خودشونو دارن و تداخلی باهم پیدا نخواهند کرد!

اما چرا این اتفاق میوفته؟ چرا وقتی اونهارو در سطح کلاس تعریف کنیم این اتفاق نمیوفته؟

جواب در فهم دقیق Stack و Heap نهفته‌س ، متغیرهایی که در متدتعریف میشن در Stack ‌ذخیره میشن و متغیرهایی که در سطح کلاس تعریف میشوند چه primitive باشند و چه آبجکت در ‌Heap ذخیره خواهند شد.

حالا این چه ارتباطی به ‌thread-safe شدن کلاس ما داره ؟

خب باید بگم که هر ترد stack مخصوص بخودش رو داره در نتیجه با این روش ما هیچ متغیری رو در هیچ حالتی با ترد دیگه‌ای به اشتراک نمی‌ذاریم و در نتیجه مشکلی در همروندی نخواهیم داشت.

فقط بیاید یه ابهامی رو برطرف کنیم ، اول مثال زیر رو ببینید :

public class UnSafeClass{ private List list; public void a(){ List mList = list; // do something } }

در کد بالا mList امن هست؟

خیر امن نیست چون ما ارجا آنرا برابر با متغیری قرار دادیم که در سطح کلاس تعریف شده و قابل دسترسی بوسیله بقیه thread هاست. یعنی اگه دوتا thread این متد رو روی یک آبجکت اجرا کنن درواقع دارن روی یک متغیر کار میکنن ???. شکل زیر در حافظه درست میشه :


اگر بخوایم مشکل حل بشه باید mlist رو توی متد خودمون new کنیم و مقادیر list رو توش کپی کنیم و از اونجا به بعد با mList کارکنیم. که شکل زیر درست بشه :

این راه بسیار ساده و بدون دردسره اما جاوا به OOP معروفه و این روش عملا همه مزیت‌های یک زبون OOP رو از شما میگیره بنابراین همیشه و همه‌جا نمیشه ازش استفاده کرد اما بسیار دم‌دستی و مطمئنه. اگر خواستید سرچ بیشتر بکنید در این رابطه کلیدواژه Confinement strategy رو در مباحث Thread جاوا سرچ کنید.

ممنون که تا اینجا همراه بودید اگر خواستید بحث کنیم راجع‌به این موضوع یا حرفی سخنی بود اینجا یا توئیتر هستم.

امن باشید :)



جاواspringThreadبرنامه‌نویسی
سرگردون ابدی
شاید از این پست‌ها خوشتان بیاید