1 00:00:00,270 --> 00:00:03,690 A countdown that makes it easy to wait for multiple threats. 2 00:00:08,580 --> 00:00:12,090 I should say we had eight threads, and each one is executing a runnable task. 3 00:00:12,420 --> 00:00:17,310 Now you wouldn't want to call thread one to join thread to thread three, thread for it to join, so 4 00:00:17,310 --> 00:00:18,060 on and so forth. 5 00:00:18,150 --> 00:00:19,830 That just seems so redundant. 6 00:00:20,280 --> 00:00:22,860 What if instead we could just say large, shorter wait. 7 00:00:22,860 --> 00:00:26,220 And then our main thread just knows to wait for every task to finish. 8 00:00:29,950 --> 00:00:34,270 Well, that's why in this lesson, you're going to use a countdown that's that awaits worker threats. 9 00:00:38,820 --> 00:00:43,620 A countdown latch allows a parent thread to await the completion of worker threads. 10 00:00:47,020 --> 00:00:51,440 And so before we start, let's take a look at the dark and grim world where we don't have countdown 11 00:00:51,440 --> 00:00:51,970 clocks. 12 00:00:52,540 --> 00:00:57,550 Imagine I actually need to run this task four times, so I would copy and paste this. 13 00:00:57,550 --> 00:00:59,950 I would call this thread three, thread four. 14 00:01:00,880 --> 00:01:04,360 Then I would have to say, throw three dots, start again. 15 00:01:04,360 --> 00:01:05,459 We should be using a thread pool. 16 00:01:05,470 --> 00:01:06,250 We'll do that later. 17 00:01:06,640 --> 00:01:08,050 Thread four starts. 18 00:01:10,550 --> 00:01:14,960 Then I would have to call Thread joined four times, this is already getting so repetitive. 19 00:01:18,720 --> 00:01:20,580 And now, if you were to run our code. 20 00:01:23,250 --> 00:01:27,180 I mean, everything works, but this is just not great, it's not good at all. 21 00:01:27,450 --> 00:01:32,310 What if we needed the task to run a thousand times or, you know, call a thousand joint methods? 22 00:01:32,670 --> 00:01:36,240 Well, I mean, in any case, we should be using a thread pool, but we'll get to that eventually. 23 00:01:36,780 --> 00:01:40,220 What I'm going to do here is delete all of these join calls. 24 00:01:41,810 --> 00:01:46,880 And I'm going to create a countdown that's where we expect to run four tasks ceremonies say countdown 25 00:01:46,880 --> 00:01:47,390 much. 26 00:01:48,850 --> 00:01:49,480 Latch. 27 00:01:50,560 --> 00:01:55,840 Is equal to a new countdown latch that counts down from four. 28 00:01:57,730 --> 00:02:02,560 Now, from within the try catch block, I'm going to call Larch .08. 29 00:02:06,930 --> 00:02:11,430 And now is are allowed to go on to magically wait until all of our tasks have been completed. 30 00:02:12,210 --> 00:02:13,250 Let's find out. 31 00:02:17,420 --> 00:02:18,260 Definitely not. 32 00:02:18,290 --> 00:02:19,850 This seems like it's going to run forever. 33 00:02:20,360 --> 00:02:23,240 The Latch opens after it countdown to zero. 34 00:02:24,050 --> 00:02:30,080 In this case, a relapse starts at four, and when we call it a wait, we're basically closing the latch. 35 00:02:30,530 --> 00:02:33,890 This latch is never going to open until it counts down to zero. 36 00:02:34,310 --> 00:02:38,600 So after we perform each task, we need to call a large dark countdown. 37 00:02:39,170 --> 00:02:42,740 So we're going to do is run a patch now pass, not patch. 38 00:02:43,040 --> 00:02:47,960 We're going to pass our large countdown much into the task method. 39 00:03:03,690 --> 00:03:09,900 And now after we finish each task, we're going to count down large dark countdown. 40 00:03:12,280 --> 00:03:15,850 For every task that executes are allowed is going to count down one. 41 00:03:16,120 --> 00:03:22,870 And so after four tasks, it's going to count down to zero, causing our alarge to open and continue 42 00:03:22,870 --> 00:03:23,920 the code inside men. 43 00:03:25,040 --> 00:03:26,450 So if we run our code. 44 00:03:28,860 --> 00:03:33,540 Oh, I'm going to have to close the previous latch and try this again. 45 00:03:34,990 --> 00:03:35,770 Everything works out. 46 00:03:37,010 --> 00:03:41,330 As our background threads are running large, that a way to close as the latch on the main thread. 47 00:03:41,930 --> 00:03:45,680 The latter will never open until every single task completes and counts down. 48 00:03:53,390 --> 00:03:58,910 And once it counts down to zero hour latch opens and whatever needed to wait inside, Maine can now 49 00:03:58,910 --> 00:03:59,660 get executed. 50 00:04:02,720 --> 00:04:06,410 That being said, you should favor reusing threads over creating new ones. 51 00:04:06,830 --> 00:04:10,670 In other words, use a thread pool that retains an active number of threads. 52 00:04:11,030 --> 00:04:16,370 And so based on our formula for CPU intensive tasks, I'm going to get the number of available course. 53 00:04:17,209 --> 00:04:22,070 So we can say it's number of threads is equal to runtime. 54 00:04:23,840 --> 00:04:27,110 Died at one time, the ones available to our up. 55 00:04:29,500 --> 00:04:34,420 Then I can create a new threat pool using the executor service class. 56 00:04:35,640 --> 00:04:36,390 Executor. 57 00:04:37,800 --> 00:04:42,720 Is equal to executor's dot new fixed thread pool. 58 00:04:48,670 --> 00:04:53,740 And now, instead of creating four different threads, what we're going to do is directly submit each 59 00:04:53,740 --> 00:04:54,220 task. 60 00:05:08,650 --> 00:05:09,010 OK. 61 00:05:09,370 --> 00:05:13,540 And as soon as you submit a task, it already starts running in the background, so we don't need these. 62 00:05:17,040 --> 00:05:18,120 You're on the application. 63 00:05:20,520 --> 00:05:23,790 Oh, we forgot to shut our thread pool down, so finally. 64 00:05:26,420 --> 00:05:30,380 We'll say executor does shutdown. 65 00:05:40,870 --> 00:05:41,440 Perfect. 66 00:05:42,460 --> 00:05:47,410 Now, let's just say you were running 11 tasks you would have to start counting, down from 11. 67 00:05:47,650 --> 00:05:51,620 If you were running 55 tasks, you would have to start counting down from 55. 68 00:05:52,150 --> 00:05:58,120 Whatever it is, make sure your countdown clock is consistent with the amount of tasks that you're executing. 69 00:05:58,990 --> 00:06:00,180 And you know what? 70 00:06:00,190 --> 00:06:02,740 Let's just say we do want to perform 11 tasks. 71 00:06:05,030 --> 00:06:11,060 All we would have to do is say for index is smaller than 11 executor does submit. 72 00:06:14,150 --> 00:06:15,890 Make sure you start counting down from 11. 73 00:06:19,200 --> 00:06:19,770 Beautiful. 74 00:06:20,860 --> 00:06:22,630 55 55. 75 00:06:25,510 --> 00:06:26,080 Nice. 76 00:06:27,240 --> 00:06:32,940 Our threat pool is reusing threads to perform 55 different tasks are our large starts counting, down 77 00:06:32,940 --> 00:06:33,780 from 55. 78 00:06:34,050 --> 00:06:38,770 And every time a task is performed, it counts down one once it gets to zero. 79 00:06:38,790 --> 00:06:44,400 Our lunch opens and whatever needs to be executed in Maine executes. 80 00:06:48,900 --> 00:06:54,900 To recap, a countdown match allows a parent thread to await the completion of worker threads.