Avatar
1
toilahtc Beginner
toilahtc Beginner
Câu hỏi MultiThread sử dụng cho bài toán đếm tăng dần
  • Tại sao count lại khác 10.000.000, bé hơn hay lớn hơn 10.000.000?
  • Dùng 3 cách để count có giá trị 10.000.000 sau khi chạy đoạn code dưới (yêu cầu vẫn chạy 50 thread song song).
  • Hàm thread.join() dùng để làm gì?
import java.util.ArrayList;

public class ThreadTest {
    static int count = 0;

    public static void main(String[] args) throws InterruptedException {
        ArrayList<Thread> list = new ArrayList<>();

        for (int i = 0; i < 50; i++) {
            Thread th = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 200000; i++) {
                        count++;
                    }
                }
            });
            th.start();
            list.add(th);
        }

        for (Thread thread : list) {
            try {
                thread.join();
            } catch (InterruptedException ex) {
            }
        }

        System.out.println("Count: "+count);
    }
}
  • Answer
multithread thread
Remain: 5
1 Answer
Avatar
tvd12 Beginner
tvd12 Beginner
The Best Answer
  1. Chương trình của em gặp vấn đề là sử dụng biến int count, nó không phải thread safe, dẫn đến bị sai
  2. Các cách giải quyết

Cách 1. Dùng join như em:

public class MultiThreadCountingTest {
    static AtomicInteger count = new AtomicInteger();
    
    public static void main(String[] args) throws Exception {
        int threadCount = 50;
        List list = new ArrayList();
        for (int i = 0; i  {
                for (int i1 = 0; i1 < 200000; i1++) {
                    count.incrementAndGet();
                }
            });
            th.start();
            list.add(th);
        }
        for (Thread thread : list) {
            thread.join();
        }
        System.out.println("Count: "+count);
    }
}

Cách 2. Dùng CountDownLatch:

public class MultiThreadCountingTest {
    static AtomicInteger count = new AtomicInteger();

    public static void main(String[] args) throws Exception {
        int threadCount = 50;
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        for (int i = 0; i  {
                for (int i1 = 0; i1 < 200000; i1++) {
                    count.incrementAndGet();
                }
                countDownLatch.countDown();
            });
            th.start();
        }
        countDownLatch.await();
        System.out.println("Count: "+count);
    }
}

Cách 3. Dùng biến count thread done:

public class MultiThreadCountingTest {
    static AtomicInteger count = new AtomicInteger();

    public static void main(String[] args) throws Exception {
        int threadCount = 50;
        AtomicInteger doneCount = new AtomicInteger();
        for (int i = 0; i  {
                for (int i1 = 0; i1 < 200000; i1++) {
                    count.incrementAndGet();
                }
                doneCount.incrementAndGet();
            });
            th.start();
        }
        while (doneCount.get() != threadCount) {
            Thread.sleep(1);
        }
        System.out.println("Count: "+count);
    }
}

  1. Join: Waits for this thread to die. An invocation of this method behaves in exactly the same way as the invocation join(0). Như vậy là nó sẽ phải đợi cho đến khi nào cái thread gọi join nó kết thúc em ạ.
  • 2
  • Reply