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
:
- 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;
- 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;
- 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);
}
}
}
}
Về nguyên tắc có liên quan gì? – SLaks
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
Câu hỏi này quá mơ hồ để được trả lời. – SLaks