2013-09-28 55 views
5

Có một mô hình nhẹ để hủy bỏ phương pháp lâu runing, mà thay thế mã như thế này:Lightweight dài chạy phương pháp hủy mô hình cho Java

public void longComputations() { 
    ... first step... 
    if (cancelled) { 
     rollbackWork(); 
     return; 
    } 
    ... second step... 
    if (cancelled) { 
     rollbackWork(); 
     return; 
    } 
    ... third step... 
    if (cancelled) { 
     rollbackWork(); 
     return; 
    } 
} 

tôi biết rằng tôi có thể làm cho một lớp công tác, chia nhỏ các bước để nhiệm vụ các đối tượng, tạo một hàng đợi và chỉ cần thực hiện các công việc theo từng bước trong vòng lặp với việc kiểm tra hủy, nhưng tôi chỉ tự hỏi là có bất kỳ mẫu cấu trúc mã đơn giản nào cho tình trạng sush.

Trả lời

4

Tôi không biết cơ chế như vậy. Vì bạn phải theo dõi công việc của mình để có thể thực hiện rollbackWork(), một giải pháp hướng đối tượng được thiết kế tốt là lựa chọn tốt nhất của bạn, nếu bạn muốn tiếp tục phát triển logic này! Thông thường, một kịch bản như vậy có thể được thực hiện bằng cách sử dụng command pattern, mà tôi vẫn thấy khá nhẹ:

// Task or Command 
public interface Command { 
    void redo(); 
    void undo(); 
} 

Một lịch trình hoặc hàng đợi sau đó có thể chăm sóc bản thực hiện như việc triển khai nhiệm vụ/lệnh, và của cán chúng trở lại theo thứ tự.

+2

+1 Mẫu lệnh goF –

+0

Tôi sẽ chấp nhận do đủ khoảng thời gian. Tuy nhiên, câu trả lời thực sự là "Không, không có cấu trúc mã đơn giản cho điều đó". Giải pháp của bạn là một chút nặng (như tôi đã nói 'chia nhỏ các bước cho các đối tượng nhiệm vụ') cho quá trình rất nhỏ, nhưng tôi nghĩ rằng đó là một thực hành tốt hơn nhiều mà liên quan đến chủ đề exteptions/thread gián đoạn. –

+0

@killer_PL: Có, sử dụng các chủ đề có thể làm phức tạp quá mức nhiệm vụ ... –

1

Nếu các bước gọi phương thức ném InterruptedException thì bạn có thể sử dụng Thread.interrupt(). Bạn sẽ vẫn cần duy trì đủ thông tin trạng thái để thực hiện khôi phục đúng cách.

Nếu các bước không thể bị gián đoạn theo cách này, bạn nên không xem xét dựa vào cơ chế Thread.stop() không được chấp nhận vì cơ chế này không an toàn.

Có vẻ như là một trong hai cách nó có ý nghĩa để làm chính xác những gì bạn mô tả: đóng gói logic luồng công việc này trong một lớp độc lập với các bước tính toán. Nó sẽ hỗ trợ hủy bỏ và/hoặc gián đoạn và chấp nhận một loạt các nhiệm vụ được thực hiện. Lưu ý rằng các nhiệm vụ được đưa vào luồng công việc phải cung cấp ít nhất hai phương pháp: một để thực hiện tính toán và một để cuộn nó trở lại.

0

Bạn có thể muốn xem xét sử dụng gói java.util.concurrent. Bạn cần phải bao gồm các bước làm việc của bạn như Callables (hoặc Runnables).

public class InterruptibleTest { 
    public static void main(String[] args) { try { 
     final ExecutorService queue = Executors.newFixedThreadPool(1); 
     queue.submit(new Callable<Void>() { @Override public Void call() { busyWait(1000); return null; } }); 
     queue.submit(new Callable<Void>() { @Override public Void call() { busyWait(1000); return null; } }); 
     queue.submit(new Callable<Void>() { @Override public Void call() { busyWait(1000); return null; } }); 
     final AtomicBoolean cancelled = new AtomicBoolean(); 
     new Thread() { @Override public void run() { 
       try { Thread.sleep(1500); } catch (InterruptedException ex) { } 
       queue.shutdownNow(); 
       cancelled.set(true); 
      } 
     }.run(); 
     if (cancelled.get()) { rollback(); } 
     queue.shutdown(); 
     System.out.println("Finished"); 
    } catch (Exception ex) { ex.printStackTrace(System.err); } } 

    public synchronized static void busyWait(int millis) { 
     System.out.println("Start"); 
     long until = System.currentTimeMillis() + millis; 
     while (System.currentTimeMillis() < until) { } 
     System.out.println("Stopped"); 
    } 
    public synchronized static void rollback() { 
     System.out.println("Rollback!"); 
    } 
} 

Lưu ý rằng shutdownNow() có thể gọi ngắt() trên chuỗi công việc hiện đang thực hiện. Bạn có thể cũng sẽ cần phải đồng bộ hóa rollback của bạn() vì shutdownNow() trả về trước khi mã không thể ngắt kết thúc thực thi.

+0

'Chủ đề mới (...). Run()'? – assylias

2

Còn bản chỉnh sửa này, không phải là mẫu? Trường hợp ngoại lệ rất rẻ, vì vậy nó phải nhanh chóng.

public void caller(){ 
    try{ 
     longComputations(); 
    } catch (MeaningfulRuntimeException e){ 
     rollbackWork(e.getStep()); 
    } 
} 

public void longComputations() { 
    ... first step... 
    checkStatus(1); 

    ... second step... 
    checkStatus(2); 

    ... third step... 
    checkStatus(3); 
} 

public void checkStatus(int step){ 
    if (cancelled) { 
     ... we may rollback here or throw an exception ... 
     throw MeaningfulRuntimeException(step); 
    } 
} 
Các vấn đề liên quan