2013-06-03 33 views
5

Bạn sẽ trả lời câu hỏi sau đây như thế nào?thực thi khối mã nguyên tử

Phương thức của lớp java chứa khối mã phải được thực thi nguyên tử. Giải thích, sử dụng pseudo-code thích hợp, làm thế nào bạn sẽ đảm bảo rằng khối mã này được thực hiện nguyên tử

tôi sẽ đạt được điều này bằng cách làm cho phương pháp này ..

public final AtomicInteger x = new AtomicInteger(0); 

sau đó đảm bảo báo cáo kết quả get trở :

x.get() 

và nếu tôi muốn tăng giá trị của x, tôi có nên làm điều này không?

x.getAndIncrement(); 
+3

Về nguyên tắc có liên quan gì? – SLaks

+0

xin lỗi tôi không chắc chắn, đây là tất cả những gì chúng tôi có cho câu hỏi. đó là một câu hỏi thi trước đây và chúng tôi đã không đưa ra câu trả lời mẫu cho nó – germantom

+1

Câu hỏi này quá mơ hồ để được trả lời. – SLaks

Trả lời

32

Câu trả lời phụ thuộc vào định nghĩa của bạn về "nguyên tử"

tôi biết ba định nghĩa giá trị atomic:

  1. nguyên tử như trong đồng bộ: chỉ một thread có thể được thực hiện mã tại một thời gian;
  2. Nguyên tử như trong ACID: tất cả hành động/khối xảy ra hoặc không có hành động/khối nào xảy ra;
  3. Nguyên tử như trong không bị gián đoạn: khi khối bắt đầu, nó không thể bị gián đoạn, ngay cả khi chuyển đổi tác vụ.

Điều đầu tiên có thể là ý nghĩa của giáo sư và rất dễ thực hiện (xem bên dưới).

Thứ hai (nguyên tử như trong ACID) có thể xấp xỉ. Xem bên dưới.

Đơn giản thứ ba không thể được đảm bảo trong Java - nó không cung cấp quyền truy cập vào các phần nguyên thủy "quan trọng" cần thiết cho tính liên tục. May mắn thay, sự cần thiết cho điều này là khá nhiều hạn chế cho hệ điều hành và trình điều khiển thiết bị.

nguyên tử như trong đồng bộ

Đây là tương đối đơn giản: chỉ cần gửi kèm theo khối code của bạn trong một khối đồng bộ.Tôi đã thể hiện nó như một khối rời rạc dưới đây, nhưng có những lựa chọn khác:

public void doSomethingQuasiAtomic() { 
    synchronized (exampleLock) { 
     // Your code block goes here. 
     // Only one thread will ever be in this block at a time. 
     ... 
    } 
} 

nguyên tử như trong ACID

Không có giải pháp chung hợp cụ thể cho ACID số nguyên tử, nhưng nó có thể xấp xỉ, cũng sử dụng mã được đồng bộ hóa. Để làm được điều này, mỗi phần của hành động phải được đảo ngược một cách an toàn.

Đây là cách tôi muốn tiếp cận nó:

Vì lợi ích của đối số, giả sử có một hành động nhiều phần dữ liệu bạn cần làm vào một đối tượng chúng ta sẽ gọi exampleObj, rằng bạn có ba hành động được thực hiện mà có thể được an toàn được đảo ngược và tất cả quyền truy cập vào example được đồng bộ hóa trên exampleLock.


    synchronized(exampleLock) { 
     boolean actionOneDone=false; 
     boolean actionTwoDone=false; 
     boolean actionThreeDone=false; 
     try { 
      actionOneDone=doActionOne(exampleObj); // or perhaps exampleObj.doActionOne(); 
      actionTwoDone=doActionTwo(exampleObj); 
      actionThreeDone=doActionThree(exampleObj); 
     } catch (Exception ex) { 
      // Whatever seems appropriate here. 
     } finally { 
      if (! (actionOneDone && actionTwoDone && actionThreeDone)) { 
       /* At least one part failed. Back out the completed actions in reverse order. 
       * Note that we never need to reverse action three since if it completed, so did the others. 
       */ 
       if (actionTwoDone) { 
        reverseActionTwo(exampleObj); // or perhaps exampleObj.reverseActionTwo(); 
       } 
       if (actionOneDone) { 
        reverseActionOne(exampleObj); 
       } 
      } 
     } 
    } 
+0

Thú vị! Tôi chỉ thấy bản thân mình cho câu trả lời này như một câu trả lời kiểm tra: P – Mifeet

+0

cũng đặt, mister! rõ ràng và súc tích. –

1

Tôi tin rằng câu trả lời sẽ là một cái gì đó như thế này:

public class A { 
    public void foo() { 
     // .. some code 
     doSomething(); // the critical part 
     // .. come code 
    } 

    public synchronized void doSomething() { // this is a synchronized method 
     // the critical code 
    } 
} 

Việc thi hành doSomething() là không thực sự nguyên tử (Disclaimer: nó rất khác so với số nguyên tử), nhưng synchronized Đảm bảo từ khóa chỉ có một luồng có thể nhập thực thi phương thức này (trên một phiên bản A). Tôi nghĩ đó là ý của họ thay vì nguyên tử.

Here là một câu hỏi khác về nguyên tử trong Java. Bạn có thể tìm thấy một cái gì đó hữu ích trong đó.

+1

Điều này rất khác với nguyên tử. Các chức năng khác vẫn có thể quan sát đối tượng ở trạng thái không nhất quán. – SLaks

+1

Đó có thể là câu hỏi được đề cập đến, nhưng phương pháp 'đồng bộ hóa 'không đảm bảo nguyên tử. –

+1

Có, nhưng câu hỏi rõ ràng là không có ý nghĩa, vì vậy tôi nghĩ rằng nó chỉ là kém thể hiện. Tôi nghĩ rằng họ có nghĩa là nguyên tử theo nghĩa là xen kẽ các hướng dẫn trong khối "nguyên tử" bị loại trừ. Tôi biết nó không phải là nguyên tử thực sự, nhưng họ nói về "khối mã" để họ có thể thậm chí không có nghĩa là "AtomicInteger' hay bất cứ điều gì. – Mifeet