Demo lợi ích của sử dụng multi thread trong Java

Chào mừng các bạn đã đến với thachleblog. Bài viết hôm nay, mình sẽ giới thiệu một chủ đề cực kỳ hay ho trong lập trình Java, đó là multi thread. Multi thread là một kỹ thuật lập trình cực kỳ quan trọng, nhưng đa phần với sinh viên mới ra trường hoặc đi làm nhưng ít có cơ hội làm việc trực tiếp, hiểu biết về multi thread cũng như khả năng áp dụng còn khá mơ hồ. Do đó, với loạt bài chia sẻ về multi thread và concurrency bắt đầu từ bài này, mình hy vọng sẽ có thể làm rõ các vấn đề trong multi thread và concurrency, mình rất mong nhận được những góp ý từ các bạn.

Giới thiệu

Multi thread định nghĩa theo kiểu hàn lâm là một kỹ thuật giúp cho một chương trình có khả năng xử lý đồng thời nhiều công việc nhằm tăng hiệu suất công việc, giảm thiểu thời gian thực hiện và tận dụng tốt tài nguyên của hệ thống. (Lưu ý là multi thread chỉ có thể chạy đồng thời trên máy tính multi core, đối với máy 1 core, các thread sẽ được switch liên tục để chạy)

Ví dụ vui

Ví dụ vui, phòng trọ mình dọn dẹp cuối tháng, có các công việc cần phải làm được liệt kê như sau:
– Lau nhà cần 15′
– Sắp xếp đồ đạc cần 15’
– Dọn đổ rác cần  10’
Phòng mình có 3 người, nếu mình sai thằng em mình làm tất thì sẽ mất tầm 40’. Nhưng nếu mình và bạn còn lại phụ cùng làm thì mỗi thằng mất 10 – 15’, toàn bộ công việc hoàn thành trong khoảng 15’.
Giả sử chương trình là dọn nhà, và 3 thằng là tài nguyên của hệ thống thì khả năng 3 thằng cùng làm song song chính là ứng dụng multi thread. Mình sẽ có chương trình cụ thể để mô phỏng ví dụ.
Sau đây là ví dụ về cách implement multi thread bằng cách implement interface Runable
Nếu như mình cho thằng em mình làm tất, giả sử ở đây mỗi việc tốn 5s (đỡ mất công chờ):

Class NonmultiThread minh họa công việc được thực hiện bằng cách thông thường:

  1. package thach.le;
  2. import java.util.concurrent.TimeUnit;
  3. public class NonMultiThread {
  4. // clean ground, it takes 5s
  5. public static void cleanGround() throws InterruptedException {
  6. System.out.println("== I am cleanning ground...");
  7. TimeUnit.SECONDS.sleep(5);
  8. System.out.println("== Complete clean ground!");
  9. }
  10.  
  11. // clean ground, it takes 5s
  12. public static void sortStuff() throws InterruptedException {
  13. System.out.println("== I am sorting stuff...");
  14. TimeUnit.SECONDS.sleep(5);
  15. System.out.println("== Complete sort stuff!");
  16. }
  17.  
  18. // clean ground, it takes 5s
  19. public static void throwGarbage() throws InterruptedException {
  20. System.out.println("== I am throwing garbage...");
  21. TimeUnit.SECONDS.sleep(5);
  22. System.out.println("== Complete throw garbage!");
  23. }
  24.  
  25. public static void main(String[] args) throws InterruptedException {
  26. System.out.println("I am doing house work...");
  27. long start = System.nanoTime();
  28.  
  29. cleanGround();
  30. sortStuff();
  31. throwGarbage();
  32.  
  33. long elapsedTime = System.nanoTime() - start;
  34. System.out.println("Complete house work!");
  35. System.out.println("Elapsed time: " + elapsedTime / 1000000000.0 + "(s)");
  36. }
  37. }

Kết quả, mỗi việc mất 5s, trung bình mất khoảng 15s

loi ich multi thread

Thử với multi thread

Các công việc implement Runable theo phương pháp cổ điển, ở các bài viết sau mình sẽ implement multi thread bằng lamda expression:

Class CleaningGround

  1. package thach.le.housework;
  2. import java.util.concurrent.TimeUnit;
  3. public class CleaningGround implements Runnable {
  4. @Override
  5. public void run() {
  6. System.out.println(== I am cleanning ground...);
  7. try {
  8. TimeUnit.SECONDS.sleep(5);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. System.out.println(== Complete clean ground!);
  13. }
  14. }

Class SortingStuff

  1. package thach.le.housework;
  2. import java.util.concurrent.TimeUnit;
  3. public class SortingStuff implements Runnable {
  4.  
  5. @Override
  6. public void run() {
  7. System.out.println(== I am sorting stuff...);
  8. try {
  9. TimeUnit.SECONDS.sleep(5);
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println(== Complete sort stuff!);
  14. }
  15. }

Class ThrowingGarbage

  1. package thach.le.housework;
  2. import java.util.concurrent.TimeUnit;
  3. public class ThrowingGarbage implements Runnable {
  4. @Override
  5. public void run() {
  6. System.out.println(== I am throwing garbage...);
  7. try {
  8. TimeUnit.SECONDS.sleep(5);
  9. } catch (InterruptedException e) {
  10. // TODO Auto-generated catch block
  11. e.printStackTrace();
  12. }
  13. System.out.println(== Complete throw garbage!);
  14. }
  15. }

Class Test

  1. package thach.le.housework;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. public class Test {
  5. public static void main(String[] args) {
  6. System.out.println(I am doing house work...);
  7. long start = System.nanoTime();
  8.  
  9. SortingStuff sortingStuff = new SortingStuff();
  10. CleaningGround cleanGround = new CleaningGround();
  11. ThrowingGarbage throwingGarbage = new ThrowingGarbage();
  12. ExecutorService executor = Executors.newFixedThreadPool(3);
  13.  
  14. executor.execute(throwingGarbage);
  15. executor.execute(sortingStuff);
  16. executor.execute(cleanGround);
  17.  
  18. // Wait until all threads are finish
  19. executor.shutdown();
  20. while (!executor.isTerminated()) {
  21. }
  22.  
  23. long elapsedTime = System.nanoTime() - start;
  24. System.out.println(Complete house work!);
  25. System.out.println(Elapsed time: + elapsedTime / 1000000000.0 + (s));
  26. }
  27. }

Kết quả:

result_multithread.jpg
Thật ấn tượng, chỉ tốn 5s!

Vừa rồi là ví dụ đơn giản về sử dụng multi thread trong Java, chúng ta có thể thấy, việc sử dụng multi thead sẽ tiết kiệm cả thời gian lẫn tài nguyên hệ thống. Trong thực tế một ứng dụng web hoặc app có thể có hàng ngàn thậm chí hàng chục ngàn request cùng một lúc, nên việc sử dụng multi thread là không thể thiếu.

Qua phần trình bày của mình, hy vọng các bạn cảm thấy hứng thú với chủ đề multi thread. Mong nhận được ý kiến đóng góp của tất cả các bạn.
Xin cảm ơn!

Tham khảo thêm:
http://www.javatpoint.com/multithreading-in-java
http://beginnersbook.com/2013/03/multithreading-in-java/
http://crunchify.com/how-to-run-multiple-threads-concurrently-in-java-executorservice-approach/

8 thoughts on “Demo lợi ích của sử dụng multi thread trong Java

  1. Pingback: Multi thread trong Java (phần 2) Runable interface và Thread abstract class – Thạch Lê blog – chia sẻ và học hỏi

  2. Pingback: Thread interference trong Java – Java technologies

  3. Pingback: Phân biệt Runable interface và Thread abstract class » Thach Le

  4. Pingback: Thread interference trong Java » Thach Le

Tham gia bình luận