Có, bạn có thể đồng bộ hóa bằng cách sử dụng mảng làm đối tượng màn hình, vì mảng (thậm chí mảng nguyên thủy) là các đối tượng trong Java.
Bạn có thể đồng bộ hóa một khối mã trên một màn hình cụ thể như thế này:
public void myMethod() {
unsynchronized_statements...
synchronized(myMonitorObject) {
synchronized_statments...
}
Đó là thực hành tốt nhất để đồng bộ hóa như vài dòng mã càng tốt.
Đồng bộ mã trên màn hình không ảnh hưởng đến màn hình theo bất kỳ cách nào, nó chỉ ảnh hưởng đến các chuỗi truy cập khối mã được đồng bộ. Trước khi thực hiện chuỗi có thể nhập vào khối mã, nó phải có 'khóa' trên màn hình. Thời gian chạy Java đảm bảo rằng nhiều nhất một luồng tại một thời điểm có thể có 'khóa' trên màn hình. Vì vậy, việc đồng bộ hóa trên mảng của bạn không cấm các khối mã không đồng bộ để truy cập nó! Bí quyết là đảm bảo rằng tất cả các thao tác bạn không muốn xảy ra đồng thời nằm trong các khối được đồng bộ hóa trên cùng một màn hình.
Vì Java không cung cấp mảng đa chiều, chỉ mảng mảng, bạn chắc chắn có thể đồng bộ hóa trên một mảng lồng nhau để đồng bộ hóa chi tiết hơn. Nếu bạn mô hình hóa mảng 2d dưới dạng một mảng các hàng, bạn chỉ có thể đồng bộ hóa trên các hàng, chứ không phải trên các cột vì trong các cột ví dụ đó không được biểu diễn dưới dạng mảng riêng biệt.
Bạn chỉ có thể đồng bộ hóa trên các giá trị mảng đơn nếu chúng không phải là primitve, do đó, Integer() thay vì int. Lưu ý rằng Integer() là một đối tượng bất biến, vì vậy bạn sẽ không thể thay đổi giá trị của nó. Một giải pháp sẽ là tạo đối tượng wrapper Cell() của riêng bạn với một getter và setter cho giá trị số chứa. Điều này sẽ cho phép bạn để cho một sợi có được một khóa trên các tế bào và thay đổi một cách an toàn giá trị của nó.
Bởi vì đó là ngày nghỉ của tôi, tôi quyết định có một số niềm vui và tạo ra một ví dụ làm việc về những gì bạn mô tả. Vâng, đây là ý tưởng của tôi về việc vui chơi.
Lớp học:
- Matrix: đại diện của một ma trận 2ngày của các tế bào
- Cell: wrapper cho một giá trị của ô ma trận
- Operation: Một hoạt động trừu tượng về một loạt các tế bào
- IncrementOperation: một Hoạt động gia tăng mỗi Giá trị ô
- ReverseOperation: hoạt động đảo ngược orde r của các tế bào
- Main: ứng dụng
Ứng dụng này bắt đầu nhiều hoạt động trên cùng một ma trận. Khối mã được đồng bộ hóa duy nhất là trong lớp Hoạt động. Nếu bạn loại bỏ đồng bộ hóa, kết quả sẽ sai vì hai thao tác đang thao tác cùng một hàng cùng một lúc.
Output khi đồng bộ:
[105, 104, 103, 102, 101]
[110, 109, 108, 107, 106]
[115, 114, 113, 112, 111]
[120, 119, 118, 117, 116]
[125, 124, 123, 122, 121]
[130, 129, 128, 127, 126]
[135, 134, 133, 132, 131]
[140, 139, 138, 137, 136]
[145, 144, 143, 142, 141]
[150, 149, 148, 147, 146]
Ví dụ đầu ra khi không đồng bộ:
[105, 4, 103, 102, 101]
[110, 9, 108, 207, 106]
[115, 14, 113, 212, 111]
[120, 19, 118, 217, 116]
[125, 124, 123, 122, 121]
[130, 129, 128, 127, 126]
[135, 34, 133, 232, 131]
[140, 139, 138, 137, 136]
[145, 144, 143, 142, 141]
[150, 149, 148, 147, 146]
Lưu ý rằng tôi đã thêm một số Thread.sleep() báo cáo trong việc triển khai hoạt động để tạo sự khác biệt giữa đồng bộ và thực hiện không đồng bộ rõ ràng hơn.
Bạn không thể đồng bộ hóa trên nguyên thủy. Một khối đồng bộ yêu cầu một đối tượng để nó có thể sử dụng khóa liên quan của nó. –
Tôi đã nói ở đâu bạn có thể đồng bộ hóa trên nguyên thủy? –
Xin chào! Tôi không muốn âm thanh có nghĩa là, chỉ cần nhìn thấy dòng đầu tiên của bạn "Có, bạn có thể đồng bộ hóa bằng cách sử dụng một mảng như đối tượng màn hình, bởi vì mảng (thậm chí nguyên thủy) là đối tượng trong Java." Bạn nói rằng bạn có thể đồng bộ trên mảng vì chúng là đối tượng. Đúng rồi. Nhưng cũng nói thêm rằng các sự kiện nguyên thủy bị đe dọa là các đối tượng, nhưng chúng không phải. Trân trọng, Tiberiu. –