runBlocking — Kotlin এ একটি Coroutine Builder যা পাস করা কোরুটিন শেষ হতে বর্তমান থ্রেডকে ব্লক করে। launch এবং async এর বিপরীতে, এটি একটি suspend ফাংশন নয় এবং সাধারণ (blocking) কোড থেকে ডাকা যেতে পারে। JetBrains ডকুমেন্টেশন, 2024 অনুযায়ী, runBlocking সিঙ্ক্রোনাস এবং অ্যাসিঙ্ক্রোনাস দুনিয়ার মধ্যে একটি সেতু হিসাবে কাজ করে, যা main ফাংশন এবং টেস্ট থেকে কোরুটিন শুরু করতে দেয়।
মূখ্য বিষয়াবলী
runBlocking হল একটি Kotlin ফাংশন যা একটি নতুন CoroutineScope তৈরি করে এবং পাস করা কোরুটিন চালু করে, বর্তমান থ্রেডকে সম্পূর্ণ শেষ হতে ব্লক করে। অন্য সকল Coroutine Builder এর বিপরীতে, runBlocking একটি suspend ফাংশন নয় এবং সাধারণ সিঙ্ক্রোনাস কোড থেকে ডাকা যেতে পারে। runBlocking এর সিগনিচার CoroutineContext এবং একটি suspend ব্লক নেয়, T টাইপের একটি ফলাফল ফেরত দেয়।
public fun <T> runBlocking(
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> T
): T
runBlocking বর্তমান থ্রেডে একটি নতুন event-loop শুরু করে। যখন কোরুটিন একটি suspend ফাংশন (যেমন delay() বা await()) কল করে, runBlocking থ্রেডকে ব্লক করে এবং স্থগিত কোরুটিনটি পুনরায় শুরু হতে একই থ্রেডে অন্য নির্ধারিত কোরুটিন চালায়। এটি সহযোগিতামূলক ব্লকিং — থ্রেডটি নিষ্ক্রিয় থাকে না বরং অন্য কোরুটিন প্রক্রিয়া করে।
runBlocking এর অন্তর্গত প্রক্রিয়া event-loop এর উপর ভিত্তি করে: যখন একটি suspend ফাংশন ডাকা হয়, runBlocking বর্তমান ব্লকের মানাগুল বন্ধ করে এবং ক্য়ূ থেকে অন্য কোরুটিন চালায়। যখন suspend ফাংশন শেষ হয়, মানাগুল পুনরায় শুরু হয়। এই চক্র তবে থেকে যায় যত্না সকল কোরুটিন শেষ না হয়।
runBlocking কোরুটিন চালানোর জন্য নিজস্ব একক-থ্রেড পুল ব্যবহার করে। Dispatchers.IO বা Default এর বিপরীতে, runBlocking থ্রেড পরিবর্তন করে না — এটি সকল কোরুটিন বর্তমান থ্রেডে পরিচালনা করে, তাদের এক্সিকিউশন ইন্টারলেভ করে। এটি একমাত্র বিল্ডার যা একই থ্রেডে মানাগুলের গারন্টি দেয়।
fun main() {
val threadName = Thread.currentThread().getName()
println("runBlocking আগে $threadName এ")
val result = runBlocking {
println("runBlocking এর মধ্যে ${Thread.currentThread().getName()} এ")
delay(500L)
"Done"
}
println("runBlocking এর পরে: $result")
}
আউটপুট দেখাবে যে সকল তিনটি println বিবরণ একই থ্রেডে করা হয়। runBlocking থ্রেড পরিবর্তন করে না বরং event-loop ব্যবহার করে একই থ্রেডের মধ্যে সহযোগিতামূলক মাল্টিটাস্কিং সংগঠিত করে।
runBlocking তিনটি পরিস্থিতিতে যুক্তিযুক্ত: কনসোল অ্যাপ্লিকেশনে main() প্রবেশ বিন্দু, suspend ফাংশনের ইউনিট টেস্ট এবং সেতু — callback-ভিত্তিক বা blocking লাইব্রেরি থেকে suspend কোড ডাকা। প্রোডাক্শন Android কোডে, প্রধান থ্রেডে এটি ব্যবহার করা কঠোরভাবে নিষিদ্ধ।
| পরিস্থিতি | প্রযোজ্যতা | বিপদ |
|---|---|---|
| main() কনসোল অ্যাপ্লিকেশনের | হ্যাঁ | কোনটি নেই — এটি প্রবেশ বিন্দু, থ্রেড UI ব্লক করে না |
| JUnit টেস্ট | হ্যাঁ | সর্বনিম্ন — টেস্ট সংজ্ঞা অনুসারে সিঙ্ক্রোনাস |
| Android UI থ্রেড | না | ANR, ল্যাগ, ইন্টারফেস জমাট যাওয়া |
| Callback → Coroutine | হ্যাঁ, সাবধানের সঙ্গে | দীর্ঘ অপারেশনে থ্রেড পুল ব্লকিং |
Android টেস্টের জন্য, runBlocking এর পরিবর্তে kotlinx-coroutines-test এর TestDispatcher ব্যবহার করুন। এটি সময় নিয়ন্ত্রণ, স্বচালিত পরিষ্কার এবং টেস্ট বিচ্ছিন্নতা প্রদান করে।
অধিকাংশ পরিস্থিতিতে, runBlocking কে অ্যাসিঙ্ক্রোনাস বিকল্প দিয়ে প্রতিস্থাপিত করা যেতে পারে এবং উচিত। Android এর জন্য, এগুলো হল viewModelScope, lifecycleScope বা উপযুক্ত ডিস্প্যাচার সহ CoroutineScope। টেস্টের জন্য — TestCoroutineDispatcher এবং runTest।
// খারাপ: Android প্রধান থ্রেডে runBlocking
runBlocking(Dispatchers.Main) {
val result = networkApi.fetchData()
textView.setText(result)
}
// ভালো: lifecycleScope
lifecycleScope.launch {
val result = withContext(Dispatchers.IO) { networkApi.fetchData() }
textView.setText(result)
}
টেস্টের জন্য, বিকল্প হল kotlinx-coroutines-test এর runTest। এটি ভিরতুয়াল সময় সহ TestCoroutineScope তৈরি করে, যা বাস্তবিক অপেক্ষা ছাড়াই বিলম্ব পরীক্ষা করতে দেয়। এটি টেস্টগুলিকে দ্রুত করে এবং নির্দেশ্যক করে।
সবচেয়ে সাধারণ পরিস্থিতি হল suspend ফাংশন পরীক্ষা করা। টেস্টে runBlocking আপনাকে আর্কিটেকচার পরিবর্তন ছাড়াই একটি কোরুটিন ফলাফলের জন্য সিঙ্ক্রোনাসলি অপেক্ষা করতে দেয়। দ্বিতীয় পরিস্থিতি হল callback API সহ লাইব্রেরি, যেখানে runBlocking এর মাধ্যমে suspend ফাংশনগুলি blocking প্রসঙ্গ থেকে ডাকা হয়।
// runBlocking এর সাথে suspend ফাংশন পরীক্ষা
class RepositoryTest {
@Test
fun `fetchUser returns correct data`() {
val repository = UserRepository(FakeApi())
val result = runBlocking {
repository.fetchUser("123")
}
assertEquals("John", result.name)
assertEquals("john@test.com", result.email)
}
}
callback এবং suspend দুনিয়ার মধ্যে সেতু নির্মাণের জন্য, callbacks এর পরিবর্তে runBlocking এর সঙ্গে CompletableDeferred ব্যবহার করুন — এটি অ্যাসিঙ্ক্রোনাস অপারেশন চেইনকে সরল করে এবং কোড পঠনিয়তা বাড়ায়।
runBlocking এর অনুচিত ব্যবহার ব্লকিং পদ্ধতি থেকে কোরুটিনে স্থানান্তরণ করার সময় সাধারণ ভুলগুলির একটি। প্রধান সমস্যাগুলি: Android এর প্রধান থ্রেডে কল করা, runBlocking কে একে অন্যের মধ্যে নেস্ট করা, অ্যাসিঙ্ক্রোনাস ফাংশনের মধ্যে ব্যবহার করা এবং runBlocking এর মাধ্যমে দীর্ঘ অপারেশন চালু করা।
সুবর্ণ নিয়ম: runBlocking একটি সেতু, প্রতিস্থাপন নয়। এটি শুধুমাত্র blocking এবং non-blocking দুনিয়াকে সংযুক্ত করতে ব্যবহার করুন। অন্য সকল কাজের জন্য, launch, async বা lifecycleScope ব্যবহার করুন।
সাধারণ প্রশ্নাবলী
runBlocking একমাত্র বিল্ডার যা suspend ফাংশন নয়। এটি বর্তমান থ্রেডে একটি event-loop শুরু করে এবং সকল কোরুটিন শেষ না হতে নিয়ন্ত্রণ ফেরত দেয় না। launch এবং async তাড়াতাড়ি নিয়ন্ত্রণ ফেরত দেয়, কোরুটিনটি পছন্দে চালায়।
সুপারিশ নয়। ViewModel এর একটি নির্মিত viewModelScope আছে যা স্বচালিতভাবে কোরুটিন পরিচালনা করে এবং ধ্বংস হলে তাদের বাতিল করে। ViewModel এ runBlocking থ্রেড ব্লক করে এবং লাইফসাইকল বাতিলকরণে সাড়া দেয় না।
kotlinx-coroutines-test লাইব্রেরি থেকে runTest ব্যবহার করুন। এটি ভিরতুয়াল সময় নিয়ন্ত্রণ, স্বচালিত বাতিলকরণ এবং নির্দেশ্যক মানাগুল সহ TestCoroutineScope প্রদান করে।
Event-loop runBlocking এর মধ্যে একটি ইভেন্ট প্রক্রিয়াকরণ চক্র। যখন একটি কোরুটিন স্থগিত হয় (যেমন delay()), event-loop একই থ্রেডে অন্য প্রস্তুত কোরুটিন চালানোতে স্যাইচ করে। এটি থ্রেড স্যাইচিং ছাড়াই মাল্টিটাস্কিং এর মায়াজাল সৃষ্টি করে।
একই থ্রেডে নেস্টেড runBlocking একটি ডেডলক সৃষ্টি করে — বাইরের ব্লক ভিতরেরটির জন্য অপেক্ষা করে, কিন্তু ভিতরেরটি বাইরেরটি শেষ না হতে শুরু হতে পারে না। আলাদা থ্রেডে এটি অনুমত কিন্তু ডিবাগিং জটিলতার কারণে দৃঢ়ভাবে নিউৎসাহিত।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন