2009-04-22 39 views
11

Gần đây tôi đã tham gia cuộc phỏng vấn và anh chàng kỹ thuật đã hỏi tôi về cách làm cho một ứng dụng an toàn chỉ.Chủ đề an toàn chủ đề - tĩnh hay không?

Vâng, sau khi giải thích chính xác lock(), ông nói rằng không phải là một ý tưởng hay để có đối tượng tĩnh.

private static readonly object _syncLock = new object(); 

Ông cho biết lý do là tĩnh làm cho đối tượng đó chậm hơn cho chủ đề khóa hơn nếu nó không tĩnh. Điều này có đúng không?

EDIT: Tuy nhiên tôi vẫn không chắc chắn. Sự khác biệt giữa ba cách tiếp cận này là gì?

private static readonly object _syncLock = new object(); 
public static readonly object _syncLock = new object(); 
private readonly object _syncLock = new object(); 

Trả lời

12

Nếu một đối tượng khóa nên tĩnh hay không phụ thuộc vào đối tượng bạn muốn khóa. Nếu bạn muốn khóa một thể hiện của một lớp, bạn không thể sử dụng một đối tượng khóa tĩnh. Nếu bạn muốn khóa dữ liệu tĩnh, bạn không thể sử dụng đối tượng khóa thể hiện. Vì vậy, có vẻ như không có bất kỳ sự lựa chọn nào.

Bạn có thể nghĩ về việc sử dụng một tĩnh hoặc một đối tượng dụ khóa để khóa truy cập vào dữ liệu ví dụ, nhưng kết quả này trong các hành vi khác nhau. Với một đối tượng khóa thể hiện bạn chỉ khóa một thể hiện trong khi một đối tượng khóa tĩnh sẽ khóa tất cả các cá thể. Vì vậy, không có sự lựa chọn để điều chỉnh hiệu suất ở đây, quá.

+0

Giải thích của bạn có ý nghĩa rất nhiều, tuy nhiên đừng quên tĩnh của nó. Không có gì từ bên ngoài có thể truy cập nó anyway. – Houman

+0

Đây cũng là những gì tôi nghĩ. Có đối tượng khóa là không tĩnh sẽ thay đổi phạm vi của khóa. –

7

Ông tuyên bố lý do là tĩnh được chạy trong thời gian chạy thay vì biên soạn và sẽ làm cho đối tượng mà chậm cho chủ đề để khóa hơn nếu nó đã không tĩnh.

Điều này thực sự không có ý nghĩa gì - tôi nghĩ người phỏng vấn không biết anh ấy đang nói về điều gì, hoặc có thể bạn đã hiểu lầm quan điểm của mình.

+0

tôi đã nghĩ chính xác điều tương tự (và gõ). –

+0

Tôi đã ghi chú. Ông nói tĩnh sẽ chậm hơn trong trường hợp này. Tôi không bảo vệ anh ấy Tôi đang cố gắng tìm ra sự thật. :) – Houman

+0

tôi đồng ý nó không có ý nghĩa – galets

0

Đôi khi trong cuộc phỏng vấn công việc tôi nói điều gì đó tôi biết là không chính xác hoặc cái gì đó là hoàn toàn vô nghĩa để xem nếu ứng cử viên một cách hiệu quả sẽ lập luận quan điểm của mình hay chỉ là từ bỏ và đồng ý.

Oh và đây là một excellent article by Jeffrey Richter trên những ứng dụng thích hợp của khóa. :)

+0

Bạn không lo lắng điều này sẽ phản tác dụng? Nếu tôi gặp một người phỏng vấn xin việc, tôi có thể rời khỏi cuộc phỏng vấn và nghĩ rằng công ty khá nghèo so với quan điểm kỹ thuật –

+1

Không, tôi phải biết nếu một người nghĩ anh ta đúng, anh ta có thể tranh luận một cách hiệu quả quan điểm của mình. Nếu không, các nhà phát triển khác trong tổ chức của tôi sẽ ăn anh ta sống. –

+3

Ngoài ra, tôi nghĩ tốt hơn là bạn có thể thuyết phục được ông chủ tiềm năng của mình. Không có gì tệ hơn một người quản lý không thể thừa nhận họ sai. –

-1

Những trường hợp khác là chính xác rằng việc chọn sử dụng trường tĩnh của trường phụ thuộc vào trạng thái (cấp lớp hoặc cấp độ cá thể) mà bạn cần khóa và không có sự khác biệt có liên quan về tốc độ khóa chinh no. NHƯNG nếu bạn thực sự chỉ cần sử dụng dữ liệu cá thể thì ứng dụng của bạn có thể chạy nhanh hơn nhiều bằng cách sử dụng lock(this) thay vì khóa tất cả các chuỗi truy cập dữ liệu BẤT CỨ ví dụ. Đó có thể là những gì người phỏng vấn nhận được - trong một ứng dụng mà nhiều luồng chỉ sử dụng dữ liệu cá thể, nó thực sự chạy nhanh hơn nếu bạn chỉ khóa thể hiện vì nó sẽ không chặn các luồng khác sử dụng các cá thể khác.

Ngược lại nếu đề đang truy cập lớp cấp (tĩnh) nhà nước thì bạn cần phải nhốt chúng tất cả với một đối tượng duy nhất. Khi tôi cần phải làm điều này, một mô hình tôi đã sử dụng là để khóa các loại của lớp như thế này:

[Edit - không phải là một ý tưởng tốt như vậy sau khi tất cả, xem ý kiến ​​dưới đây]

lock(typeof(MyClass)) 
{ 
    // use class-level data 
} 

Điều này tránh sự cần thiết phải tạo trường đối tượng tĩnh.

+0

Ý tưởng hay để khóa (typeof (MyClass)). 1 Nhưng bạn không nên luôn luôn sử dụng nó cho cùng một lý do bạn không nên luôn luôn sử dụng khóa (điều này). Bạn sẽ khóa toàn bộ cá thể hoặc tất cả dữ liệu tĩnh trong khi bạn chỉ có thể cần khóa một phần nhỏ của nó. Tạo các đối tượng khóa chuyên dụng cho phép bạn có nhiều khóa trên mỗi loại ot và thực hiện khóa chi tiết hơn. –

+1

Xin lỗi, tôi phải thu hồi phiếu bầu của mình. Chỉ cần học được mã này thực sự tệ đến mức nào. Xem http://bytes.com/groups/net-c/249277-dont-lock-type-objects để biết chi tiết. –

+1

Nó trở nên tồi tệ hơn. khóa (điều này) là một lựa chọn không kém phần quan trọng - xem http://msdn.microsoft.com/de-de/magazine/cc188793(en-us).aspx để biết chi tiết. Bài học kinh nghiệm: Chỉ khóa trên cá thể riêng hoặc các đối tượng tĩnh của một kiểu tham chiếu! –

0

Sử dụng đối tượng không tĩnh cho khóa bất cứ khi nào bạn cần đảm bảo cùng một phiên bản không bị thao tác bởi các chuỗi khác nhau cùng một lúc.

Cho phép nói rằng bạn có một số lớp Danh sách, với phương pháp Sắp xếp lại đặc biệt chấp nhận một số đối số lạ. Xem xét nếu bạn cần sắp xếp lại 100 danh sách khác nhau trong một số quy trình song song. Bạn chỉ quan tâm rằng các luồng khác nhau không thao tác cùng một danh sách cùng một lúc, vì nó có thể ảnh hưởng đến logic sắp xếp lại của bạn. Bạn không cần một khóa tĩnh, vì bạn không quan tâm khi danh sách khác nhau đang được thao tác cùng một lúc.

Ví dụ đơn giản về kịch bản có khóa tĩnh, khởi tạo một số dữ liệu tĩnh, nơi bạn muốn đảm bảo tải logic chỉ chạy một lần. Giống như một số Cache hoặc Singleton.

+0

Tất cả những gì bạn nói là hợp lệ. Tuy nhiên xin vui lòng giải thích cho tôi những gì sự khác biệt nó làm cho nếu đối tượng là tư nhân anyway. nếu không có chủ đề riêng tư của nó có thể truy cập nó từ bên ngoài anyway. Vì vậy, whats điểm của việc có một tĩnh tư nhân trong trường hợp này? Riêng tư giết chết ý nghĩa của tĩnh. – Houman

+0

Không thực sự, được tư nhân không có bất kỳ mối quan hệ với tĩnh. Trong thực tế, cho nó là có chỉ cho khóa, nó phải được tư nhân. Bạn muốn các ổ khóa diễn ra bên trong việc thực hiện của lớp, do đó, không có điểm nào để lộ ra thế giới bên ngoài. Trong các ví dụ tải, bạn muốn khóa được xử lý nội bộ khi bạn gọi một thuộc tính tĩnh như: MyClass.Current. Nó là việc thực hiện hiện tại sử dụng khóa để đảm bảo rằng nó không tải trường hợp hai lần. – eglasius

0

Nếu bạn chỉ có một thể hiện của một lớp chia sẻ giữa nhiều luồng, bạn có thể sử dụng đối tượng bình thường. nhưng nếu bạn có nhiều đối tượng của một lớp chia sẻ giữa nhiều luồng, bạn phải sử dụng đối tượng tĩnh tĩnh.

Mặt khác, với đối tượng bình thường bạn có thể quản lý đồng thời cho một thể hiện của một lớp và với đối tượng tĩnh bạn có thể quản lý đồng thời trong phạm vi của tất cả trường hợp của một lớp.