Có nghĩa là hai luồng không thể thay đổi dữ liệu cơ bản cùng một lúc? Hoặc nó có nghĩa là đoạn mã đã cho sẽ chạy với kết quả có thể dự đoán được khi nhiều luồng đang thực thi đoạn mã đó?
Có nghĩa là hai luồng không thể thay đổi dữ liệu cơ bản cùng một lúc? Hoặc nó có nghĩa là đoạn mã đã cho sẽ chạy với kết quả có thể dự đoán được khi nhiều luồng đang thực thi đoạn mã đó?
Câu trả lời:
Từ Wikipedia:
An toàn luồng là một khái niệm lập trình máy tính áp dụng trong ngữ cảnh của các chương trình đa luồng. Một đoạn mã là an toàn luồng nếu nó hoạt động chính xác trong khi thực hiện đồng thời bởi nhiều luồng. Cụ thể, nó phải đáp ứng nhu cầu cho nhiều luồng truy cập vào cùng một dữ liệu được chia sẻ và nhu cầu về một phần dữ liệu được chia sẻ chỉ được truy cập bởi một luồng tại bất kỳ thời điểm nào.
Có một số cách để đạt được an toàn luồng:
Nhập lại:
Viết mã theo cách mà nó có thể được thực thi một phần bởi một tác vụ, được nhập lại bởi một tác vụ khác và sau đó được tiếp tục từ tác vụ ban đầu. Điều này đòi hỏi phải lưu thông tin trạng thái trong các biến cục bộ cho từng tác vụ, thường là trên ngăn xếp của nó, thay vì trong các biến tĩnh hoặc toàn cục.
Loại trừ lẫn nhau:
Truy cập vào dữ liệu chia sẻ được tuần tự hóa bằng các cơ chế đảm bảo chỉ có một luồng đọc hoặc ghi dữ liệu được chia sẻ bất cứ lúc nào. Cần hết sức cẩn thận nếu một đoạn mã truy cập vào nhiều đoạn dữ liệu được chia sẻ Các vấn đề về giáo dục bao gồm các điều kiện chủng tộc, bế tắc, sinh động, chết đói và nhiều bệnh khác được liệt kê trong nhiều sách giáo khoa của hệ điều hành.
Lưu trữ theo luồng cục bộ:
Các biến được bản địa hóa để mỗi luồng có bản sao riêng. Các biến này giữ giá trị của chúng trên chương trình con và các ranh giới mã khác và an toàn cho luồng vì chúng là cục bộ của từng luồng, mặc dù mã truy cập chúng có thể được cấp lại.
Hoạt động nguyên tử:
Dữ liệu được chia sẻ được truy cập bằng cách sử dụng các hoạt động nguyên tử không thể bị gián đoạn bởi các luồng khác. Điều này thường yêu cầu sử dụng các hướng dẫn ngôn ngữ máy đặc biệt, có thể có sẵn trong thư viện thời gian chạy. Vì các hoạt động là nguyên tử, dữ liệu chia sẻ luôn được giữ ở trạng thái hợp lệ, bất kể các luồng khác truy cập vào nó. Hoạt động nguyên tử tạo thành cơ sở của nhiều cơ chế khóa luồng.
đọc thêm:
http://en.wikipedia.org/wiki/Thread_safe
bằng tiếng Đức: http://de.wikipedia.org/wiki/Threads Richheit
bằng tiếng Pháp: http://fr.wikipedia.org/wiki/Threadsafe (rất ngắn)
Mã an toàn chủ đề là mã sẽ hoạt động ngay cả khi nhiều Chủ đề đang thực thi đồng thời.
Một câu hỏi nhiều thông tin hơn là điều gì làm cho mã không phải là luồng an toàn - và câu trả lời là có bốn điều kiện phải đúng ... Hãy tưởng tượng đoạn mã sau (và đó là bản dịch ngôn ngữ máy)
totalRequests = totalRequests + 1
MOV EAX, [totalRequests] // load memory for tot Requests into register
INC EAX // update register
MOV [totalRequests], EAX // store updated value back to memory
Tôi thích định nghĩa từ Thực hành đồng thời Java của Brian Goetz vì tính toàn diện của nó
"Một lớp là an toàn luồng nếu nó hoạt động chính xác khi được truy cập từ nhiều luồng, bất kể việc lập lịch trình hoặc xen kẽ việc thực thi các luồng đó bởi môi trường thời gian chạy và không có sự đồng bộ hóa hoặc phối hợp khác trên một phần của mã gọi. "
Như những người khác đã chỉ ra, an toàn luồng có nghĩa là một đoạn mã sẽ hoạt động mà không có lỗi nếu nó được sử dụng bởi nhiều hơn một luồng cùng một lúc.
Điều đáng lưu ý là điều này đôi khi phải trả giá, thời gian của máy tính và mã hóa phức tạp hơn, vì vậy nó không phải lúc nào cũng được mong muốn. Nếu một lớp có thể được sử dụng một cách an toàn trên chỉ một luồng, có thể tốt hơn để làm như vậy.
Ví dụ, Java có hai lớp gần như tương đương StringBuffer
và StringBuilder
. Sự khác biệt là StringBuffer
an toàn luồng, do đó, một thể hiện của một StringBuffer
luồng có thể được sử dụng bởi nhiều luồng cùng một lúc. StringBuilder
không an toàn cho luồng và được thiết kế như một sự thay thế hiệu năng cao hơn cho những trường hợp đó (đại đa số) khi Chuỗi được xây dựng chỉ bởi một luồng.
Một cách dễ dàng hơn để hiểu nó, đó là những gì làm cho mã không an toàn cho chuỗi. Có hai vấn đề chính sẽ làm cho một ứng dụng luồng có hành vi không mong muốn.
Truy cập biến chia sẻ mà không khóa
Biến này có thể được sửa đổi bởi một luồng khác trong khi thực hiện chức năng. Bạn muốn ngăn chặn nó bằng một cơ chế khóa để chắc chắn về hành vi của chức năng của bạn. Nguyên tắc chung là giữ khóa trong thời gian ngắn nhất có thể.
Bế tắc gây ra bởi sự phụ thuộc lẫn nhau vào biến chia sẻ
Nếu bạn có hai biến chung A và B. Trong một chức năng, bạn khóa A trước sau đó bạn khóa B. Trong một chức năng khác, bạn bắt đầu khóa B và sau một thời gian, bạn khóa A. Điều này là một bế tắc tiềm năng trong đó chức năng đầu tiên sẽ đợi B được mở khóa khi chức năng thứ hai sẽ chờ A được mở khóa. Vấn đề này có thể sẽ không xảy ra trong môi trường phát triển của bạn và chỉ thỉnh thoảng. Để tránh nó, tất cả các khóa phải luôn theo cùng một thứ tự.
Có và không.
An toàn luồng là nhiều hơn một chút so với việc đảm bảo dữ liệu chia sẻ của bạn chỉ được truy cập bởi một luồng mỗi lần. Bạn phải đảm bảo truy cập tuần tự vào dữ liệu được chia sẻ, đồng thời tránh các điều kiện chủng tộc , bế tắc , sinh động và bỏ đói tài nguyên .
Kết quả không thể đoán trước khi nhiều luồng đang chạy không phải là điều kiện bắt buộc của mã an toàn luồng, nhưng nó thường là sản phẩm phụ. Ví dụ: bạn có thể có một sơ đồ nhà sản xuất-người tiêu dùng được thiết lập với hàng đợi dùng chung, một luồng sản xuất và một vài luồng tiêu dùng và luồng dữ liệu có thể dự đoán được một cách hoàn hảo. Nếu bạn bắt đầu giới thiệu nhiều người tiêu dùng hơn, bạn sẽ thấy nhiều kết quả tìm kiếm ngẫu nhiên hơn.
Về bản chất, nhiều thứ có thể sai trong môi trường đa luồng (hướng dẫn sắp xếp lại, các đối tượng được xây dựng một phần, cùng một biến có các giá trị khác nhau trong các luồng khác nhau do lưu vào bộ đệm ở cấp CPU, v.v.).
Tôi thích định nghĩa được đưa ra bởi Java Concurrency in Practice :
[Phần mã] an toàn cho luồng nếu nó hoạt động chính xác khi được truy cập từ nhiều luồng, bất kể lập lịch hoặc xen kẽ việc thực thi các luồng đó bởi môi trường thời gian chạy và không có đồng bộ hóa bổ sung hoặc phối hợp khác trên một phần của mã gọi.
Bởi chính xác, họ có nghĩa là chương trình hành xử tuân thủ các thông số kỹ thuật của nó.
Ví dụ
Hãy tưởng tượng rằng bạn thực hiện một truy cập. Bạn có thể nói rằng nó hoạt động chính xác nếu:
counter.next()
không bao giờ trả về một giá trị đã được trả về trước đó (chúng tôi giả sử không có tràn vv để đơn giản)Một bộ đếm an toàn của luồng sẽ hoạt động theo các quy tắc đó bất kể có bao nhiêu luồng truy cập đồng thời (thường không phải là trường hợp thực hiện ngây thơ).
Đơn giản - mã sẽ chạy tốt nếu nhiều luồng đang thực thi mã này cùng một lúc.
Đừng nhầm lẫn sự an toàn của chủ đề với tính xác định. Mã an toàn chủ đề cũng có thể không xác định. Với những khó khăn trong việc gỡ lỗi các vấn đề với mã luồng, đây có lẽ là trường hợp bình thường. :-)
An toàn luồng chỉ đơn giản là đảm bảo rằng khi một luồng đang sửa đổi hoặc đọc dữ liệu được chia sẻ, không có luồng nào khác có thể truy cập nó theo cách thay đổi dữ liệu. Nếu mã của bạn phụ thuộc vào một thứ tự nhất định để thực thi cho chính xác, thì bạn cần các cơ chế đồng bộ hóa khác ngoài các cơ chế được yêu cầu về an toàn luồng để đảm bảo điều này.
Tôi muốn thêm một số thông tin trên đầu câu trả lời tốt khác.
An toàn luồng ngụ ý nhiều luồng có thể ghi / đọc dữ liệu trong cùng một đối tượng mà không có lỗi không nhất quán bộ nhớ. Trong chương trình đa luồng cao, chương trình an toàn luồng không gây ra tác dụng phụ cho dữ liệu chia sẻ .
Hãy xem câu hỏi SE này để biết thêm chi tiết:
Chủ đề an toàn có nghĩa là gì?
Chương trình an toàn chủ đề đảm bảo tính nhất quán bộ nhớ .
Từ trang tài liệu oracle về API đồng thời nâng cao:
Thuộc tính nhất quán bộ nhớ:
Chương 17 của Đặc tả ngôn ngữ Java ™ xác định mối quan hệ xảy ra trước khi hoạt động của bộ nhớ như đọc và ghi các biến được chia sẻ. Các kết quả của một lần ghi bởi một luồng được đảm bảo hiển thị cho một lần đọc bởi một luồng khác chỉ khi thao tác ghi xảy ra - trước thao tác đọc .
Các cấu trúc synchronized
và volatile
, cũng như Thread.start()
và Thread.join()
các phương thức, có thể hình thành xảy ra - trước các mối quan hệ.
Các phương thức của tất cả các lớp trong java.util.concurrent
và các gói con của nó mở rộng các đảm bảo này đến đồng bộ hóa ở mức cao hơn. Đặc biệt:
Runnable
sự kiện Executor
xảy ra - trước khi việc thực thi của nó bắt đầu. Tương tự cho các Callables gửi đến một ExecutorService
.Future
hành động xảy ra trước khi truy xuất kết quả thông qua Future.get()
trong một luồng khác.Lock.unlock, Semaphore.release, and CountDownLatch.countDown
các hành động xảy ra trước các phương thức "thu nhận" thành công, chẳng hạn như Lock.lock, Semaphore.acquire, Condition.await, and CountDownLatch.await
trên cùng một đối tượng đồng bộ hóa trong một luồng khác.Exchanger
, các hành động trước exchange()
trong mỗi luồng xảy ra - trước các luồng tiếp theo với trao đổi tương ứng () trong luồng khác.CyclicBarrier.await
và Phaser.awaitAdvance
(cũng như các biến thể của nó) xảy ra trước các hành động được thực hiện bởi hành động rào cản và các hành động được thực hiện bởi hành động rào cản xảy ra - trước các hành động sau khi trả lại thành công từ sự chờ đợi tương ứng trong các luồng khác.Để hoàn thành các câu trả lời khác:
Đồng bộ hóa chỉ là một vấn đề đáng lo ngại khi mã trong phương thức của bạn thực hiện một trong hai điều sau:
Điều này có nghĩa là các biến được định nghĩa trong phương thức của bạn luôn là các luồng an toàn. Mỗi lệnh gọi đến một phương thức có phiên bản riêng của các biến này. Nếu phương thức được gọi bởi một luồng khác hoặc bởi cùng một luồng hoặc ngay cả khi phương thức đó tự gọi (đệ quy), các giá trị của các biến này không được chia sẻ.
Lập lịch trình chủ đề không được đảm bảo là vòng tròn . Một tác vụ hoàn toàn có thể hog CPU với chi phí của các luồng có cùng mức ưu tiên. Bạn có thể sử dụng Thread.yield () để có lương tâm. Bạn có thể sử dụng (trong java) Thread.setP Warriority (Thread.NORM_PRIORITY-1) để hạ mức độ ưu tiên của luồng
Cộng với sự cẩn thận của:
Vâng và vâng. Nó ngụ ý rằng dữ liệu không được sửa đổi bởi nhiều hơn một luồng cùng một lúc. Tuy nhiên, chương trình của bạn có thể hoạt động như mong đợi và có vẻ an toàn cho chủ đề, ngay cả khi về cơ bản là không.
Lưu ý rằng kết quả không dự đoán được là kết quả của 'điều kiện chủng tộc' có thể dẫn đến dữ liệu bị sửa đổi theo thứ tự khác với dự kiến.
Hãy trả lời điều này bằng ví dụ:
class NonThreadSafe {
private int counter = 0;
public boolean countTo10() {
count = count + 1;
return (count == 10);
}
Các countTo10
phương pháp bổ sung thêm một đến quầy thu ngân và sau đó trả về true nếu số lượng đã đạt 10 Nó chỉ nên trở lại một khi sự thật.
Điều này sẽ hoạt động miễn là chỉ có một luồng đang chạy mã. Nếu hai luồng chạy mã cùng một lúc các vấn đề khác nhau có thể xảy ra.
Ví dụ: nếu số bắt đầu là 9, một luồng có thể thêm 1 để đếm (tạo 10) nhưng sau đó một luồng thứ hai có thể nhập phương thức và thêm 1 lần nữa (tạo 11) trước khi luồng đầu tiên có cơ hội thực hiện so sánh với 10 Sau đó, cả hai luồng thực hiện so sánh và thấy rằng số đó là 11 và không trả về đúng.
Vì vậy, mã này không phải là chủ đề an toàn.
Về bản chất, tất cả các vấn đề đa luồng được gây ra bởi một số biến thể của loại vấn đề này.
Giải pháp là đảm bảo rằng việc bổ sung và so sánh không thể tách rời (ví dụ bằng cách bao quanh hai câu lệnh bằng một loại mã đồng bộ hóa nào đó) hoặc bằng cách nghĩ ra một giải pháp không yêu cầu hai thao tác. Mã như vậy sẽ được an toàn chủ đề.
Ít nhất là trong C ++, tôi nghĩ về chủ đề an toàn như một chút sai lầm ở chỗ nó để lại rất nhiều tên. Để an toàn cho chuỗi, mã thường phải chủ động về nó. Nó thường không phải là một chất lượng thụ động.
Để một lớp được an toàn, nó phải có các tính năng "phụ" để thêm chi phí. Các tính năng này là một phần của việc triển khai lớp và nói chung, ẩn khỏi giao diện. Đó là, các luồng khác nhau có thể truy cập bất kỳ thành viên nào của lớp mà không phải lo lắng về việc xung đột với truy cập đồng thời bởi một luồng khác VÀ có thể làm như vậy một cách rất lười biếng, sử dụng kiểu mã hóa thông thường của con người thông thường, mà không phải làm tất cả những thứ đồng bộ hóa điên rồ đó đã được đưa vào ruột của mã được gọi.
Và đây là lý do tại sao một số người thích sử dụng thuật ngữ được đồng bộ hóa nội bộ .
Có ba bộ thuật ngữ chính cho những ý tưởng này mà tôi đã gặp. Đầu tiên và trong lịch sử phổ biến hơn (nhưng tệ hơn) là:
Thứ hai (và tốt hơn) là:
Thứ ba là:
chủ đề an toàn ~ bằng chứng chủ đề ~ đồng bộ nội bộ
Một ví dụ về hệ thống được đồng bộ hóa nội bộ (còn gọi là an toàn luồng hoặc chứng minh luồng ) là một nhà hàng nơi chủ nhà chào đón bạn ở cửa và không cho phép bạn xếp hàng. Chủ nhà là một phần trong cơ chế của nhà hàng để giao dịch với nhiều khách hàng và có thể sử dụng một số thủ thuật khá phức tạp để tối ưu hóa chỗ ngồi của khách hàng đang chờ, như tính đến quy mô của bữa tiệc của họ, hoặc họ trông như thế nào hoặc thậm chí nhận đặt phòng qua điện thoại. Nhà hàng được đồng bộ hóa nội bộ vì tất cả những thứ này là một phần của giao diện để tương tác với nó.
không an toàn luồng (nhưng đẹp) ~ tương thích luồng ~ được đồng bộ hóa bên ngoài ~ luồng tự do
Giả sử bạn đến ngân hàng. Có một dòng, tức là ganh đua cho các giao dịch viên ngân hàng. Bởi vì bạn không phải là một kẻ man rợ, bạn nhận ra rằng điều tốt nhất để làm giữa lúc tranh giành tài nguyên là xếp hàng như một sinh vật văn minh. Không ai về mặt kỹ thuật làm cho bạn làm điều này. Chúng tôi hy vọng bạn có chương trình xã hội cần thiết để tự làm điều đó. Theo nghĩa này, tiền sảnh ngân hàng được đồng bộ hóa bên ngoài. Chúng ta có nên nói rằng nó không an toàn? đó là những gì ngụ ý là nếu bạn đi với thread-safe , thread-an toàn bộ thuật ngữ lưỡng cực. Nó không phải là một bộ điều khoản rất tốt. Thuật ngữ tốt hơn được đồng bộ hóa bên ngoài,Sảnh ngân hàng không bị nhiều khách hàng truy cập, nhưng nó cũng không thực hiện công việc đồng bộ hóa chúng. Các khách hàng tự làm điều đó.
Điều này cũng được gọi là "miễn phí luồng", trong đó "miễn phí" giống như "không có chấy" - hoặc trong trường hợp này là khóa. Vâng, chính xác hơn, đồng bộ nguyên thủy. Điều đó không có nghĩa là mã có thể chạy trên nhiều luồng mà không cần các nguyên hàm đó. Điều đó chỉ có nghĩa là nó không đi kèm với chúng đã được cài đặt và tùy thuộc vào bạn, người sử dụng mã, để tự cài đặt chúng theo cách bạn thấy phù hợp. Việc cài đặt các nguyên hàm đồng bộ hóa của riêng bạn có thể khó khăn và đòi hỏi phải suy nghĩ kỹ về mã, nhưng cũng có thể dẫn đến chương trình nhanh nhất có thể bằng cách cho phép bạn tùy chỉnh cách chương trình thực thi trên các CPU siêu phân luồng ngày nay.
không an toàn chủ đề (và xấu) ~ chủ đề thù địch ~ không đồng bộ
Một ví dụ tương tự hàng ngày của một hệ thống thù địch chủ đề là một số người bị giật với một chiếc xe thể thao từ chối sử dụng đèn nháy và thay đổi làn đường willy-nilly. Phong cách lái xe của họ là chủ đề thù địch hoặc không đồng bộ vì bạn không có cách nào để phối hợp với họ và điều này có thể dẫn đến sự tranh chấp cho cùng một làn đường, không có độ phân giải, và do đó, một tai nạn khi hai chiếc xe cố gắng chiếm cùng một không gian, mà không có bất kỳ giao thức nào ngăn chặn điều này Mô hình này cũng có thể được coi rộng rãi hơn là chống xã hội, mà tôi thích vì nó ít cụ thể hơn đối với các luồng và vì vậy thường áp dụng cho nhiều lĩnh vực lập trình.
Bộ thuật ngữ đầu tiên và lâu đời nhất không thể phân biệt rõ hơn giữa tính thù địch của luồng và khả năng tương thích của luồng . Khả năng tương thích luồng là thụ động hơn so với cái gọi là an toàn luồng, nhưng điều đó không có nghĩa là mã được gọi là không an toàn khi sử dụng luồng đồng thời. Nó chỉ có nghĩa là nó thụ động về việc đồng bộ hóa sẽ cho phép điều này, đưa nó vào mã gọi, thay vì cung cấp nó như là một phần của việc triển khai nội bộ. Tương thích luồng là cách mã có thể được viết theo mặc định trong hầu hết các trường hợp, nhưng điều này cũng đáng buồn thường được coi là không an toàn của luồng, như thể nó vốn là chống an toàn, đó là một điểm gây nhầm lẫn lớn cho các lập trình viên.
LƯU Ý: Nhiều hướng dẫn sử dụng phần mềm thực sự sử dụng thuật ngữ "an toàn luồng" để chỉ "tương thích luồng", làm tăng thêm sự nhầm lẫn cho những gì đã là một mớ hỗn độn! Tôi tránh thuật ngữ "an toàn luồng" và "không an toàn luồng" bằng mọi giá vì lý do này, vì một số nguồn sẽ gọi một cái gì đó là "an toàn luồng" trong khi những người khác gọi nó là "không an toàn luồng" vì họ không đồng ý về việc bạn phải đáp ứng một số tiêu chuẩn bổ sung về an toàn (nguyên thủy đồng bộ hóa) hay chỉ KHÔNG được thù địch để được coi là "an toàn". Vì vậy, tránh các điều khoản đó và sử dụng các thuật ngữ thông minh hơn thay vào đó, để tránh các thông tin sai lệch nguy hiểm với các kỹ sư khác.
Về cơ bản, mục tiêu của chúng tôi là lật đổ sự hỗn loạn.
Chúng tôi làm điều đó bằng cách tạo ra các hệ thống xác định mà chúng tôi có thể dựa vào. Sự quyết đoán là tốn kém, chủ yếu là do chi phí cơ hội của việc mất song song, đường ống và sắp xếp lại. Chúng tôi cố gắng giảm thiểu số lượng quyết định mà chúng tôi cần để giữ chi phí của mình ở mức thấp, đồng thời tránh đưa ra các quyết định sẽ làm xói mòn thêm những gì mà chúng tôi có thể chi trả.
Đồng bộ hóa các chủ đề là về việc tăng thứ tự và giảm sự hỗn loạn. Các cấp độ mà bạn làm điều này tương ứng với các điều khoản được đề cập ở trên. Mức cao nhất có nghĩa là một hệ thống hành xử theo cách hoàn toàn có thể dự đoán được mọi lúc. Cấp độ thứ hai có nghĩa là hệ thống hoạt động đủ tốt để gọi mã có thể phát hiện một cách đáng tin cậy. Ví dụ: đánh thức giả trong một biến điều kiện hoặc không khóa được mutex vì nó chưa sẵn sàng. Cấp độ thứ ba có nghĩa là hệ thống không hoạt động đủ tốt để chơi với bất kỳ ai khác và chỉ có thể EVER được chạy một luồng mà không phát sinh sự hỗn loạn.
Thay vì nghĩ mã hoặc các lớp là luồng an toàn hay không, tôi nghĩ sẽ hữu ích hơn khi nghĩ các hành động là an toàn luồng. Hai hành động là luồng an toàn nếu chúng sẽ hoạt động như được chỉ định khi chạy từ bối cảnh luồng tùy ý. Trong nhiều trường hợp, các lớp sẽ hỗ trợ một số kết hợp các hành động theo kiểu an toàn luồng và các trường hợp khác thì không.
Ví dụ, nhiều bộ sưu tập như danh sách mảng và bộ băm sẽ đảm bảo rằng nếu ban đầu chúng chỉ được truy cập bằng một luồng và chúng không bao giờ được sửa đổi sau khi tham chiếu trở nên hiển thị với bất kỳ luồng nào khác, chúng có thể được đọc theo cách tùy ý của chủ đề mà không can thiệp.
Thú vị hơn, một số bộ sưu tập băm như bộ không gốc chung trong .NET, có thể đảm bảo rằng miễn là không có mục nào bị xóa và chỉ cung cấp một luồng duy nhất ghi cho chúng, bất kỳ luồng nào cố gắng đọc bộ sưu tập sẽ hoạt động như thể truy cập vào một bộ sưu tập trong đó các cập nhật có thể bị trì hoãn và xảy ra theo thứ tự tùy ý, nhưng nếu không thì sẽ hoạt động bình thường. Nếu luồng số 1 thêm X và sau đó là Y, và luồng số 2 tìm và thấy Y và sau đó là X, thì luồng số 2 có thể thấy rằng Y tồn tại nhưng X thì không; hành vi đó có "an toàn cho luồng" hay không sẽ phụ thuộc vào việc luồng số 2 có được chuẩn bị để đối phó với khả năng đó hay không.
Lưu ý cuối cùng, một số lớp - đặc biệt là chặn các thư viện truyền thông - có thể có phương thức "đóng" hoặc "Loại bỏ" an toàn cho luồng đối với tất cả các phương thức khác, nhưng không có phương thức nào khác an toàn cho luồng đối với lẫn nhau. Nếu một luồng thực hiện yêu cầu đọc chặn và người dùng chương trình nhấp vào "hủy", sẽ không có cách nào để yêu cầu đóng được đưa ra bởi luồng đang cố thực hiện đọc. Tuy nhiên, yêu cầu đóng / loại bỏ có thể đặt cờ không đồng bộ sẽ khiến yêu cầu đọc bị hủy càng sớm càng tốt. Khi đóng được thực hiện trên bất kỳ luồng nào, đối tượng sẽ trở nên vô dụng và mọi nỗ lực trong các hành động trong tương lai sẽ thất bại ngay lập tức,