Tại sao cần shutdown of forked jvm
Tôi đang viết một chương trình Java sử dụng rất nhiều CPU vì bản chất của những gì nó làm. Tuy nhiên, rất nhiều trong số đó có thể chạy song song và tôi đã làm cho chương trình của mình đa luồng Khi tôi chạy nó, dường như chỉ sử dụng một CPU cho đến khi nó cần nhiều hơn thì nó sử dụng CPU khác - có bất cứ điều gì tôi có thể làm trong Java để buộc các luồng khác nhau chạy trên các lõi khác nhau/CPU?
Tôi giải thích phần này của câu hỏi của bạn là có nghĩa là bạn đã giải quyết vấn đề làm cho ứng dụng của bạn có khả năng đa luồng. Và mặc dù vậy, nó không ngay lập tức bắt đầu sử dụng nhiều lõi. Câu trả lời cho "có cách nào để ép buộc ..." là (AFAIK) không trực tiếp. JVM của bạn và/hoặc Hệ điều hành máy chủ quyết định sẽ sử dụng bao nhiêu luồng 'gốc' và cách các luồng đó được ánh xạ tới các bộ xử lý vật lý. Bạn có một số tùy chọn để điều chỉnh. Ví dụ: tôi đã tìm thấy trang này trong đó nói về cách điều chỉnh Java luồng trên Solaris. Và trang này nói về những thứ khác có thể làm chậm một ứng dụng đa luồng. The most convenient and reliable file storage service Receive your personal cloud storage with 2Gb of space for free Có hai cách cơ bản để đa luồng trong Java. Mỗi tác vụ logic bạn tạo bằng các phương thức này sẽ chạy trên lõi mới khi cần và có sẵn. Phương thức một: xác định đối tượng Runnable hoặc Thread (có thể lấy Runnable trong hàm tạo) và bắt đầu chạy với phương thức Thread.start (). Nó sẽ thực thi trên bất kỳ lõi nào mà HĐH cung cấp cho nó - nói chung là loại ít tải hơn. Hướng dẫn: Xác định và bắt đầu chủ đề Phương pháp hai: xác định các đối tượng triển khai giao diện Runnable (nếu chúng không trả về giá trị) hoặc Callable (nếu có), chứa mã xử lý của bạn. Truyền các nhiệm vụ này cho ExecutorService từ gói Java.util.conc hiện. Lớp Java.util.concản.Executors có một loạt các phương thức để tạo ra các loại ExecutorService tiêu chuẩn, hữu ích. Liên kết để hướng dẫn thực thi. Từ kinh nghiệm cá nhân, các nhóm luồng cố định và bộ nhớ cache của Executors rất tốt, mặc dù bạn sẽ muốn Tweak đếm số luồng. Runtime.getR.78 (). AvailableProcessors () có thể được sử dụng vào thời gian chạy để đếm các lõi có sẵn. Bạn sẽ cần tắt các nhóm luồng khi ứng dụng của bạn hoàn tất, nếu không ứng dụng sẽ không thoát vì các luồng ThreadPool vẫn chạy. Để có được hiệu suất đa lõi tốt đôi khi rất khó và có nhiều vấn đề:
Một vấn đề khác: kiểm soát công việc là khó khăn! Một thực hành tốt là có một luồng trình quản lý tạo và gửi các tác vụ, sau đó một vài luồng làm việc với hàng đợi công việc (sử dụng ExecutorService). Tôi chỉ chạm vào những điểm chính ở đây - lập trình đa luồng được coi là một trong những môn học lập trình khó nhất bởi nhiều chuyên gia. Nó không trực quan, phức tạp và trừu tượng thường yếu. Chỉnh sửa - Ví dụ sử dụng ExecutorService:
Trước tiên, bạn nên tự chứng minh rằng chương trình của bạn sẽ chạy nhanh hơn trên nhiều lõi. Nhiều hệ điều hành đặt nỗ lực vào việc chạy các luồng chương trình trên cùng một lõi bất cứ khi nào có thể. Chạy trên cùng một lõi có nhiều lợi thế. Bộ đệm CPU nóng, có nghĩa là dữ liệu cho chương trình đó được tải vào CPU. Các đối tượng khóa/màn hình/đồng bộ hóa nằm trong bộ đệm CPU, điều đó có nghĩa là các CPU khác không cần thực hiện các hoạt động đồng bộ hóa bộ đệm trên xe buýt (đắt tiền!). Một điều có thể rất dễ dàng khiến chương trình của bạn chạy trên cùng một CPU mọi lúc là sử dụng quá mức các khóa và bộ nhớ dùng chung. Chủ đề của bạn không nên nói chuyện với nhau. Các chủ đề của bạn càng ít sử dụng cùng một đối tượng trong cùng một bộ nhớ thì chúng sẽ càng chạy trên các CPU khác nhau. Họ càng thường xuyên sử dụng cùng một bộ nhớ, họ càng thường xuyên phải chờ đợi chuỗi khác. Bất cứ khi nào HĐH nhìn thấy một khối luồng cho luồng khác, nó sẽ chạy luồng đó trên cùng CPU bất cứ khi nào có thể. Nó giảm dung lượng bộ nhớ di chuyển trên bus liên CPU. Đó là những gì tôi đoán là gây ra những gì bạn thấy trong chương trình của bạn. Đầu tiên, tôi khuyên bạn nên đọc "Đồng thời trong thực tiễn" của Brian Goetz . Đây là cuốn sách hay nhất mô tả đồng thời Java. Đồng thời là 'dễ học, khó làm chủ'. Tôi khuyên bạn nên đọc nhiều về chủ đề này trước khi thử nó. Rất dễ dàng để có được một chương trình đa luồng hoạt động chính xác 99,9% thời gian và thất bại 0,1%. Tuy nhiên, đây là một số mẹo để bạn bắt đầu: Có hai cách phổ biến để làm cho chương trình sử dụng nhiều hơn một lõi:
Ở cấp độ thấp nhất, người ta có thể tạo và hủy chủ đề . Java giúp dễ dàng tạo các luồng theo cách đa nền tảng di động. Vì nó có xu hướng tốn kém để tạo và hủy các luồng mọi lúc, Java hiện bao gồm Executors để tạo nhóm luồng có thể sử dụng lại. Các tác vụ có thể được gán cho người thi hành và kết quả có thể được truy xuất thông qua một đối tượng Tương lai. Thông thường, một người có một nhiệm vụ có thể được chia thành các nhiệm vụ nhỏ hơn, nhưng kết quả cuối cùng cần phải được đưa lại với nhau. Ví dụ, với một sắp xếp hợp nhất, người ta có thể chia danh sách thành các phần nhỏ hơn và nhỏ hơn, cho đến khi một người có mọi lõi thực hiện việc sắp xếp. Tuy nhiên, khi mỗi danh sách con được sắp xếp, nó cần được hợp nhất để có được danh sách được sắp xếp cuối cùng. Vì đây là vấn đề "phân chia và chinh phục" khá phổ biến, nên có một khung công tác JSR có thể xử lý phân phối và tham gia cơ bản. Khung này có thể sẽ được bao gồm trong Java 7. Flexible, reliable and affordable cloud hosting Sign up and get $50 bonus within 30-day! Bạn nên viết chương trình của mình để thực hiện công việc của nó dưới dạng lot của Callable được trao cho ExecutorService và được thực hiện với invokeAll (...). Sau đó, bạn có thể chọn một triển khai phù hợp trong thời gian chạy từ lớp Executors. Một gợi ý sẽ là gọi Executors.newFixedThreadPool () với một số gần tương ứng với số lõi cpu để tiếp tục bận. Bạn có thể sử dụng API bên dưới từ Executors với Java 8
Do cơ chế đánh cắp công việc, các luồng nhàn rỗi ăn cắp các nhiệm vụ từ hàng đợi nhiệm vụ của các luồng bận rộn và thông lượng tổng thể sẽ tăng lên. Từ
grepcode , việc triển khai
Điều dễ nhất để làm là chia chương trình của bạn thành nhiều quy trình. HĐH sẽ phân bổ chúng trên các lõi. Khó hơn một chút là chia chương trình của bạn thành nhiều luồng và tin tưởng JVM để phân bổ chúng đúng cách. Đây là - nói chung - những gì mọi người làm để sử dụng phần cứng có sẵn. Chỉnh sửa Làm thế nào một chương trình đa xử lý có thể "dễ dàng" hơn? Đây là một bước trong một đường ống dẫn.
Mỗi bước trong đường ống có cấu trúc tương tự nhau. 9 dòng trên không cho bất kỳ xử lý được bao gồm. Đây có thể không phải là hiệu quả tuyệt đối nhất. Nhưng nó rất dễ. Cấu trúc tổng thể của các quy trình đồng thời của bạn không phải là vấn đề JVM. Đó là một vấn đề hệ điều hành, vì vậy hãy sử dụng Shell.
Điều duy nhất còn lại là tìm ra một số tuần tự hóa cho các đối tượng dữ liệu của bạn trong đường ống dẫn. Tiêu chuẩn nối tiếp hoạt động tốt. Đọc http://Java.Sun.com/developer/technicalArticles/Programming/serialization/ để biết gợi ý về cách tuần tự hóa. Bạn có thể thay thế Tôi nghĩ vấn đề này có liên quan đến Java Khung công tác song song (JPPF). Sử dụng điều này bạn có thể chạy các công việc khác nhau trên các bộ xử lý khác nhau. |