这是否意味着两个线程不能同时更改底层数据?或者它是否意味着当多个线程执行给定的代码段时,该代码段将以可预测的结果运行?
当前回答
简单地说,如果许多线程同时执行这段代码,代码将运行良好。
其他回答
我喜欢Brian Goetz的Java并发实践中的定义,因为它的全面性
如果一个类在从多个线程访问时行为正确,那么它就是线程安全的,而不管运行时环境对这些线程的执行是如何调度或交错的,并且在调用代码方面没有额外的同步或其他协调。
一个更容易理解的方法是,是什么使代码不是线程安全的。有两个主要问题会使线程应用程序产生不需要的行为。
Accessing shared variable without locking This variable could be modified by another thread while executing the function. You want to prevent it with a locking mechanism to be sure of the behavior of your function. General rule of thumb is to keep the lock for the shortest time possible. Deadlock caused by mutual dependency on shared variable If you have two shared variable A and B. In one function, you lock A first then later you lock B. In another function, you start locking B and after a while, you lock A. This is a potential deadlock where first function will wait for B to be unlocked when second function will wait for A to be unlocked. This issue will probably not occur in your development environment and only from time to time. To avoid it, all locks must always be in the same order.
线程安全代码按照指定的方式工作,即使由不同的线程同时输入。这通常意味着,应该不间断地运行的内部数据结构或操作受到保护,不会同时进行不同的修改。
是也不是。
线程安全不仅仅是确保共享数据一次只能被一个线程访问。您必须确保对共享数据的顺序访问,同时避免竞争条件、死锁、活动锁和资源短缺。
当多个线程同时运行时,不可预知的结果并不是线程安全代码的必要条件,但这通常是一种副产品。例如,您可以使用一个共享队列、一个生产者线程和几个消费者线程来设置生产者-消费者方案,并且数据流可能完全可预测。如果你开始引入更多的消费者,你会看到更多随机的结果。
完成其他回答:
只有当方法中的代码做以下两件事之一时,同步才会令人担忧:
使用一些非线程安全的外部资源。 读取或更改持久对象或类字段
这意味着在方法中定义的变量总是线程安全的。对方法的每次调用都有自己版本的这些变量。如果方法是由另一个线程调用的,或者是由同一线程调用的,甚至是方法调用自身(递归),这些变量的值是不共享的。
线程调度不保证是循环的。一个任务可能会以牺牲相同优先级的线程为代价完全占用CPU。你可以使用Thread.yield()来获得良心。你可以使用(java) thread . setpriority (thread . norm_priority -1)来降低线程的优先级
另外还要注意:
迭代这些“线程安全”结构的应用程序的巨大运行时成本(已经被其他人提到)。 Thread.sleep(5000)应该休眠5秒。但是,如果有人更改了系统时间,您可能会睡很长时间或根本没有时间。操作系统记录唤醒时间是绝对的,而不是相对的。