Atomicboolean là gì

Boolean là lớp bao bọc xung quanh boolean nguyên thủy. Nó có thể được tự động tạo từ boolean bởi trình biên dịch (chuyển đổi quyền anh) hoặc được chuyển đổi thành boolean (chuyển đổi unboxing). Đây không phải là trường hợp của AtomicBoolean trong đó nó là một lớp riêng được thiết kế cho mục đích tương tranh.

Do đó hai lớp có ngữ nghĩa khác nhau ở cấp độ ngôn ngữ:Boolean b = new Boolean(true); AtomicBoolean ab = new AtomicBoolean(true); System.out.println(true == b);  // automatic unboxing of Boolean variable System.out.println(true == ab);  // compiler error

Boolean là một đối tượng giá trị bất biến. Nó được thiết kế để không thay đổi và được thực hiện cuối cùng để thực thi điều đó. Java.lang.Boolean đã có từ 1.0.

AtomicBoolean có thể thay đổi và được thiết kế để được cập nhật sao cho giá trị cập nhật được hiển thị trên các luồng. AtomicBoolean đã được giới thiệu với Java 5.

Đây là những khái niệm hoàn toàn khác nhau, đó là lý do tại sao AtomicBoolean không được thiết kế để mở rộng Boolean. Bạn không thể thay thế một đối tượng có thể thay đổi cho một đối tượng bất biến mà không phá hỏng các bất biến dự kiến ​​của mã bằng cách sử dụng nó. Mã mong đợi nhận được một giá trị bất biến có thể bị phá vỡ nếu phiên bản nguyên tử có thể được thông qua ở vị trí của nó.

Vì vậy, đây là trường hợp sử dụng: nếu AtomicBoolean được giới thiệu là thứ thay thế cho Boolean, bạn có thể có trường hợp một lớp được tạo trước khi thay đổi này có thể mong đợi một cách hợp lý rằng trong một phương thức nào đó trả về Boolean, nó không cần phải vượt qua phòng thủ bản sao trên tài khoản của Boolean là bất biến. Nếu tham chiếu được trả về tình cờ được khởi tạo từ một nguồn thay đổi sử dụng AtomicBoolean thay vì Boolean, thì trường đó có thể được sửa đổi bằng cách gọi phương thức trả về Boolean, bằng cách chuyển nó sang AtomicBoolean.

Các lớp nguyên tử được thiết kế để làm việc với các bản cập nhật đồng thời (như là một cải tiến trên volatile), nhưng cách hiệu quả nhất để thiết kế mã đồng thời là sử dụng các giá trị bất biến. Vì vậy, hãy cẩn thận đừng nhầm lẫn AtomicBoolean với "Boolean bạn sử dụng khi viết mã đa luồng".

Một trường hợp sử dụng là AtomicBoolean không mở rộng Boolean. Vì vậy, nếu bạn có một phương pháp như:void foo (Boolean b) { doStuff(); }

Sau đó, bạn không thể truyền AtomicBoolean làm tham số cho foo. (Bạn sẽ phải gọi phương thức get() của AtomicBoolean.)

Chúng không thể tự động đóng hộp, vì vậy chúng không thể được sử dụng trong các điều kiện, ví dụ:// Explodey if (someAtomicBoolean) { }

Thí dụ:void doSomething( final Boolean flag ) { final boolean before = flag.booleanValue(); do0( flag ); final boolean after = flag.booleanValue(); assert before == after; if ( flag.booleanValue() ) { do1(); } if ( flag.booleanValue() ) { do2(); } }

có thể cho một kết quả khácvoid doSomething( final AtomicBoolean flag ) { final boolean before = flag.get(); do0( flag ); final boolean after = flag.get(); assert (before == after) || (before != after); if ( flag.get() ) { do1(); } if ( flag.get() ) { do2(); } }

bởi vì một AtomicBoolean có thể thay đổi giá trị của nó trong khi Boolean không thể.

Trong trường hợp đầu tiên, do1() và do2() đều được gọi hoặc không ai trong số họ.

Trong trường hợp thứ hai, cả hai, hoặc không ai trong số chúng có thể được gọi nếu giá trị AtomicBoolean 'được sửa đổi đồng thời.

Bởi vì Boolean luôn ở đó và luôn được định nghĩa là bất biến, nên AtomicBoolean, được giới thiệu nhiều sau đó, không thể thay thế cho Boolean bởi vì nó hoạt động khác nhau và mã hóa dựa trên tính bất biến của Boolean có thể bị phá hủy.

Lưu ý rằng Boolean không thể được thay thế cho AtomicBoolean và ngược lại . Họ chỉ không tương thích trong ngữ nghĩa của họ.

Bởi vì Boolean là bất biến. Xem: Tại sao lớp Wrapper như Boolean trong Java là bất biến? và câu trả lời của tôi:


Bởi vì 2 là 2. Nó sẽ không là 3 vào ngày mai.

Bất biến luôn được ưu tiên làm mặc định, đặc biệt là trong các tình huống đa luồng, và nó giúp cho việc đọc mã dễ dàng hơn và dễ bảo trì hơn. Trường hợp điển hình: API Java Date, được xử lý với các lỗi thiết kế. Nếu Date không thay đổi, API sẽ được sắp xếp hợp lý. Tôi sẽ biết các hoạt động Date sẽ tạo ngày mới và sẽ không bao giờ phải tìm kiếm các API sửa đổi chúng.

Đọc Đồng thời trong thực tiễn để hiểu tầm quan trọng thực sự của các loại bất biến.

Nhưng cũng lưu ý rằng nếu vì lý do nào đó bạn muốn các loại có thể thay đổi, hãy sử dụng AtomicIntegerAtomicBoolean, v.v ... Tại sao Atomic? Bởi vì bằng cách giới thiệu tính đột biến, bạn đã giới thiệu một nhu cầu về an toàn luồng. Điều mà bạn sẽ không cần nếu các loại của bạn không thay đổi, vì vậy, khi sử dụng các loại có thể thay đổi, bạn cũng phải trả giá khi nghĩ về an toàn luồng và sử dụng các loại từ gói concurrent. Chào mừng đến với thế giới tuyệt vời của lập trình đồng thời.

Ngoài ra, với Boolean - Tôi thách bạn đặt tên cho một thao tác mà bạn có thể muốn thực hiện để quan tâm xem Boolean có thể thay đổi hay không. Đặt thành đúng? Sử dụng myBool = true. Đó là một sự phân công lại, không phải là đột biến. Phủ định? myBool = !myBool. Cùng một quy tắc. Lưu ý rằng tính bất biến là một tính năng, không phải là một ràng buộc, vì vậy nếu bạn có thể cung cấp nó, bạn nên - và trong những trường hợp này, tất nhiên bạn có thể.

Lưu ý điều này cũng áp dụng cho các loại khác. Điều tinh tế nhất với các số nguyên là count++, nhưng đó chỉ là count = count + 1, trừ khi bạn quan tâm đến việc nhận giá trị nguyên tử ... trong trường hợp đó sử dụng AtomicInteger có thể thay đổi.

Trường hợp sử dụng chính đầu tiên của các hoạt động nguyên tử (đôi khi được gói gọn) trong bất kỳ ngôn ngữ nào là ngữ nghĩa so sánh và hoán đổi - một khối xây dựng cơ bản của các ứng dụng đồng thời.

Việc sử dụng chính thứ hai là để che giấu sự phức tạp của việc đặt hàng rào bộ nhớ chính xác, cần thiết cho ngữ nghĩa của mô hình bộ nhớ.

Trong Java Atomic * gói gọn cả hai thứ trên, cái trước - với mã gốc cụ thể của nền tảng và cái sau với sự trợ giúp của từ khóa volatile.

Video liên quan