Ngay cả một CPU đơn lẻ cũng có thể thực hiện "nhiều thứ cùng một lúc" theo nghĩa lỏng lẻo, nhưng chúng không thực sự song song. Bạn có thể bắt đầu 100 luồng để chạy trên một lõi đơn và chúng sẽ nhận được lát thời gian trong đó mỗi chuỗi có thể chạy một vài hướng dẫn, do đó tạo ra ấn tượng rằng tất cả chúng đều đang thực thi cùng một lúc.
Như tôi đã nói trong một bài SO: multithreading on dual core machine?
Các chủ đề hạn thường bao gồm ba lớp trừu tượng:
- đề tài là chủ đề đưa ra bởi các ứng dụng và được ánh xạ N: M để :
- Chủ đề hạt nhân, là các chuỗi được quản lý bởi hệ điều hành, được ánh xạ N: M tới:
- Chủ đề phần cứng, là các tài nguyên thực tế có sẵn.
Chủ đề Java là chủ đề người dùng. 4 lõi trong CPU của bạn được tính là các chuỗi phần cứng. Vì ánh xạ là N: M trên các lớp, bạn có thể thấy rằng bạn có thể có một số luồng người dùng được ánh xạ tới một số chuỗi phần cứng nhỏ hơn.
Bây giờ, sau khi nói điều này, nói chung có hai loại hoạt động chủ đề, mỗi quirks riêng của họ:
- I/O đề: những chủ đề dành phần lớn thời gian của họ chờ đợi vào đọc/ghi các hoạt động từ một luồng và bị chặn trong thời gian chờ đợi (chúng không được lên lịch thực hiện cho đến khi một sự kiện xảy ra để đánh thức chúng). Có ánh sáng trên CPU và rất nhiều trong số chúng có thể chạy đồng thời ngay cả trên một lõi đơn.
- Chủ đề tính toán: các chuỗi này thực hiện rất nhiều thao tác thu thập số và sử dụng CPU đến mức tối đa. Thường bắt đầu từ hơn (2x số lõi khả dụng), các chủ đề như vậy sẽ làm giảm hiệu suất, vì CPU có một số đơn vị chức năng giới hạn: ALU, FPU, v.v.
Lớp thứ hai của chủ đề trên cho phép bạn thực sự thấy lợi ích hoặc chạy một chương trình java đa luồng trên CPU quad-core của bạn. Dưới đây là một ví dụ đơn giản của một chương trình mà thực hiện bình phương của 1.000.000.000 số tuần tự đầu tiên và sau đó song song sử dụng một hồ bơi thread với 4 chủ đề:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
class ThreadTask implements Runnable {
private int total = 0;
public ThreadTask(int total) {
this.total = total;
}
@Override
public void run() {
int value = 0;
for(int i = 0; i < total; i++) {
value = i * i;
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
int total = 1000000000;
long start = System.currentTimeMillis();
long value = 0;
for(int i = 0; i < total; i++) {
value = i * i;
}
long stop = System.currentTimeMillis();
System.out.println((stop - start) + " ms");
ExecutorService exec = Executors.newFixedThreadPool(4);
start = System.currentTimeMillis();
for(int i = 0; i < 4; i++) {
exec.submit(new ThreadTask(total/4));
}
exec.shutdown();
exec.awaitTermination(10, TimeUnit.SECONDS);
stop = System.currentTimeMillis();
System.out.println((stop - start) + " ms");
}
}
Hãy thoải mái để điều chỉnh giá trị của total
nếu nó đang chạy quá nhanh . Bây giờ tôi đang làm việc trên một chiếc netbook với Intel Atom, vì vậy nó không thực sự nhanh chóng.
Đã đi trước và thêm thẻ đa luồng vào đây - nó không chỉ là một câu hỏi trung tâm Java. Hy vọng rằng bạn sẽ nhận được một số câu trả lời tuyệt vời. – Makoto
Bài viết bạn đọc có lẽ là từ thời gian trước các bộ vi xử lý đa lõi, vì vậy hãy chỉ sử dụng máy tính đa xử lý có thể sử dụng nó. – Hurda