Có cách nào để giết một chuỗi con sau một số giới hạn thời gian cụ thể trong Java không? Chỉnh sửa: Ngoài ra thread cụ thể này có thể bị chặn trong trường hợp xấu nhất của nó (Thread được sử dụng để chờ sửa đổi tập tin và chặn cho đến khi sự kiện này xảy ra), vì vậy im không chắc chắn rằng ngắt() sẽ thành công?Giết chủ đề sau một số giới hạn thời gian được chỉ định trong Java
Trả lời
Sử dụng ExecutorService
để thực hiện Runnable
, kiểm tra các phương pháp trong đó bạn có thể chỉ định thời gian chờ. Ví dụ.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
Đây Task
thực hiện khóa học Runnable
.
Các đề xuất tốt, nhưng ExecutorService có thể hết thời gian chờ ngay cả khi nó bị chặn không? – Traker
Nó sẽ làm gián đoạn luồng, vâng. Nếu bạn muốn sử dụng nó, hãy sử dụng 'ExecutorService # awaitTermination()', cũng xem ví dụ trong phần giới thiệu của Javadoc. – BalusC
IMHO, 'invokeAll' là quá mức cần thiết. Chỉ cần sử dụng 'executor.submit (new Task()). Get (10, TimeUnit.MINUTES);' –
Tại sao không interrupt()
sau một thời gian cụ thể? Chủ đề sinh ra của bạn sẽ phải có khả năng xử lý một số InterruptedException
đúng cách.
Xem bài viết này (http://www.javaspecialists.eu/archive/Issue056.html) để biết thêm thông tin về cách tắt chủ đề một cách rõ ràng.
Xem thêm Khung công tác/Tương lai, cung cấp các phương pháp hữu ích để thu thập kết quả và/hoặc chấm dứt chuỗi trong giới hạn thời gian cụ thể.
Chuỗi chỉ cần trả lời 'InterruptedException' nếu nó thực hiện cuộc gọi có thể ném nó. Nếu nó đang quay trong một vòng lặp, nó phải kiểm tra cờ ngắt riêng của nó bằng cách sử dụng 'Thread.isInterrupted()' (hoặc chỉ 'Thread.interrupted()', ngụ ý luồng hiện tại). –
Giết chủ đề thường là một ý tưởng tồi vì các lý do liên quan đến tài liệu API cho Thread
.
Nếu bạn chết khi chết, hãy sử dụng một quy trình hoàn toàn mới.
Nếu không, điều bình thường là phải có phiếu thăm dò chủ đề System.nanoTime
, thăm dò ý kiến (có thể volatile
) gắn cờ, xếp hàng "thuốc độc" hoặc thứ gì đó có tính chất đó.
Giết chủ đề có thể rất quan trọng, nếu bạn không sở hữu mã mà luồng này chạy, và bạn cần đảm bảo rằng anh ta đã chết. Đôi khi bạn phải có cả hai mã chạy trong cùng một địa chỉ ảo. –
@Elazar Nó gần như chắc chắn quan trọng hơn là quá trình này vẫn ổn định. –
Quyền của Brian, làm gián đoạn việc này an toàn hơn là "dừng" chuỗi đó.
Điều gì sẽ xảy ra nếu chủ đề đang khóa trên một đối tượng giữa sửa đổi và đột nhiên bị dừng lại (điều này làm cho khóa được giải phóng)? Bạn nhận được kết quả lạ.
Không trực tiếp; Tôi nghĩ cách đơn giản nhất là tham gia() trên chuỗi đó với giới hạn thời gian đó và ngắt chuỗi nếu nó không được thực hiện vào lúc kết thúc.
Vì vậy,
Thread t = ...
t.join(timelimit);
if (t.isAlive) t.interrupt();
Thông báo tôi đã sử dụng ngắt thay vì thực sự giết chết nó, nó là an toàn hơn nhiều. Tôi cũng khuyên bạn nên sử dụng các nhà thực thi thay vì trực tiếp thao tác các chủ đề.
Không sử dụng destroy()
vì điều đó không thực hiện bất kỳ thao tác dọn dẹp nào.
Cách đơn giản nhất là sử dụng join()
, như
try {
thread.join();
} catch (InterruptedException e) {//log exception...}
Bạn có thể sử dụng một ExecutorService
. Điều đó sẽ làm cho rất nhiều ý nghĩa nếu bạn có một số chủ đề chạy đồng thời. Nếu bạn có nhu cầu sinh ra các luồng mới trong khi các luồng khác đang chạy, bạn có thể kết hợp nó với một số BlockingQueue
.
A ThreadPoolExecutor
(an ExecutorService
-thực hiện) có thể tham số BlockingQueue
làm đối số và bạn có thể chỉ cần thêm chuỗi mới vào hàng đợi. Khi bạn hoàn thành, bạn chỉ cần chấm dứt số ThreadPoolExecutor
.
private BlockingQueue<Runnable> queue;
...
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, new Long(1000),
TimeUnit.MILLISECONDS, this.queue);
Bạn có thể đếm tổng số chủ đề được thêm vào hàng đợi. Khi bạn nghĩ rằng bạn đã hoàn thành (hàng đợi trống rỗng, có lẽ?) Chỉ cần so sánh số này với số
if (issuedThreads == pool.getCompletedTaskCount()) {
pool.shutdown();
}
Nếu hai kết thúc, bạn đã hoàn tất. Một cách khác để chấm dứt các hồ bơi là để chờ đợi một giây trong một vòng lặp:
try {
while (!this.pool.awaitTermination(1000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {//log exception...}
Bạn có thể sử dụng AOP và một @Timeable
chú thích cho phương pháp của bạn từ jcabi-aspects (Tôi là một nhà phát triển):
@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
// do something time consuming
}
Khi đạt đến giới hạn thời gian, chuỗi của bạn sẽ nhận được interrupted()
cờ được đặt thành true
và đó là công việc của bạn để xử lý tình huống này một cách chính xác và ngừng thực thi. Thông thường nó được thực hiện bởi Thread.sleep(..)
.
Một số thay đổi hữu ích đã được giới thiệu như là một phần của JEP 266 trong CompletableFuture
kể từ Java 9. Sử dụng orTimeout phương pháp, bây giờ, chúng ta có thể viết nó thích:
CompletableFuture.runAsync(thread::run)
.orTimeout(30, TimeUnit.SECONDS)
.exceptionally(throwable -> {
log.error("An error occurred", throwable);
return null;
});
Trong Java 8, không may, bạn nên sử dụng thêm một số mã. Dưới đây là một ví dụ về việc sử dụng mô hình đoàn với sự giúp đỡ của Lombok:
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.TimeoutException;
import static lombok.AccessLevel.PRIVATE;
import lombok.AllArgsConstructor;
import lombok.experimental.Delegate;
@AllArgsConstructor(access = PRIVATE)
public class TimeoutableCompletableFuture<T> extends CompletableFuture<T> {
public static TimeoutableCompletableFuture<Void> runAsync(
Runnable runnable) {
return new TimeoutableCompletableFuture<>(
CompletableFuture.runAsync(runnable));
}
@Delegate
private final CompletableFuture<T> baseFuture;
public TimeoutableCompletableFuture<T> orTimeout(Duration duration) {
final CompletableFuture<T> otherFuture = new CompletableFuture<>();
Executors.newScheduledThreadPool(
1,
new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("timeoutable-%d")
.build())
.schedule(() -> {
TimeoutException ex = new TimeoutException(
"Timeout after " + duration);
return otherFuture.completeExceptionally(ex);
}, duration.toMillis(), MILLISECONDS);
return new TimeoutableCompletableFuture<>(
baseFuture.applyToEither(otherFuture, a -> a));
}
}
Tất nhiên, các mã trên một cách dễ dàng có thể được viết lại như chỉ là một phương thức tĩnh:
public static CompletableFuture<Void> runAsyncOrTimeout(
Runnable runnable, long timeout, TimeUnit unit) {
CompletableFuture<Void> other = new CompletableFuture<>();
Executors.newScheduledThreadPool(
1,
new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("timeoutafter-%d")
.build())
.schedule(() -> {
TimeoutException ex = new TimeoutException(
"Timeout after " + timeout);
return other.completeExceptionally(ex);
}, timeout, unit);
return CompletableFuture.runAsync(runnable).applyToEither(other, a -> a);
}
- 1. Thời gian giới hạn một phương thức trong C#
- 2. Giới hạn số lượng chủ đề thực hiện một phương thức tại một thời điểm
- 3. Giới hạn thời gian đối với từng chủ đề với ExecutorService
- 4. Drools: Quy tắc giới hạn thời gian
- 5. nginx auth_basic giới hạn thời gian
- 6. Giới hạn số hàng được trả về ở phía máy chủ (giới hạn bắt buộc)
- 7. Khi chạy, làm thế nào tôi có thể giới hạn số lượng các chủ đề java
- 8. Giới hạn giá trị của tham số trong một hàm tạo AT THIẾT KẾ THỜI GIAN
- 9. Tránh giới hạn thời gian thực thi PHP
- 10. Python: làm thế nào tôi có thể nhận được một sợi để tự giết sau một thời gian chờ?
- 11. Thời gian chủ đề JMS để sống
- 12. Giết chặn bị chặn :: Chủ đề
- 13. Chỉ định giới hạn bộ nhớ với hadoop
- 14. Thời gian chờ nhiệm vụ của Celery/giới hạn thời gian cho các cửa sổ?
- 15. Giới hạn số lượng kết nối đồng thời trong Apache2
- 16. Trong Rails Migrations, số được chỉ định cho: giới hạn trên một số nguyên đại diện cho là gì?
- 17. GetBufferLock hết thời gian cho chủ đề
- 18. Giết chủ đề, thực sự!
- 19. Erlang và giới hạn bản ghi thời gian chạy
- 20. Giới hạn thời gian thực thi cho một kịch bản Lua được gọi từ C API
- 21. PHP: Mã hóa các tập lệnh chạy dài khi máy chủ áp đặt giới hạn thời gian thực hiện
- 22. Kill Process sau một thời gian nhất định + C#
- 23. Làm thế nào để giới hạn thời gian thực hiện của một hàm trong javascript?
- 24. Knockout.js: định dạng đầu vào thời gian và giới hạn giá trị
- 25. C# Giết tất cả chủ đề
- 26. Ngoại lệ LINQ lạ (Chỉ số ngoài giới hạn)
- 27. Chỉ định tham số loại bộ sưu tập chung trong thời gian chạy (Java Reflection)
- 28. Cách đặt giới hạn thời gian cho mã Ruby chạy
- 29. Vòng lặp ngắt sau khoảng thời gian được chỉ định trong Matlab
- 30. Đặt giới hạn hết hạn để readLine()?
bạn đang sử dụng gì để chờ đợi sửa đổi tập tin? Object.wait() hoặc cái gì khác? – mdma
Thực ra tôi đang sử dụng đồng hồ bấm giờ để tìm kiếm các sửa đổi tệp và đặc biệt 'watchService.take()' sẽ chặn cho đến khi một tệp đã được tạo/xóa. – Traker