我是java新手。我有点混淆了线程安全和同步。线程安全意味着一个方法或类实例可以被多个线程同时使用,而不会出现任何问题。其中同步意味着一次只能有一个线程运行。
那么它们是如何相互关联的呢?
线程安全:线程安全程序保护其数据不受内存一致性错误的影响。在高度多线程程序中,线程安全程序不会对共享数据(对象)的多个线程的多个读/写操作产生任何副作用。不同的线程可以共享和修改对象数据,而不会出现一致性错误。
synchronized
是实现线程安全代码的一种基本方法。
有关更多详细信息,请参阅以下 SE 问题:
“同步”是什么意思?
您可以通过使用高级并发API实现线程安全。本文档页提供了实现线程安全的良好编程结构。
锁定对象支持简化许多并发应用程序的锁定习惯用法。
并发收集使得管理大型数据集合变得更加容易,并且可以极大地减少对同步的需求。
原子变量具有最小化同步和帮助避免内存一致性错误的特性。
线程本地随机(在 JDK 7 中)提供从多个线程高效生成伪随机数的功能。
有关其他编程结构,请参考java.util.concurrent和java.util.concurrent.atomic包。
相关 SE 问题:
同步与锁定
线程安全是程序需要的行为,其中< code>synchronized块帮助您实现该行为。还有其他获得线程安全的方法,例如不可变的类/对象。希望这有所帮助。
实践中Java并发给出的线程安全的定义是:
如果从多个线程访问一个类时,该类的行为正确,则该类是线程安全的,而不管运行时环境对这些线程的执行的调度或交错,并且调用代码方面没有额外的同步或其他协调。
例如,java.text.SimpleDateFormat对象具有内部可变状态,当调用解析或格式化的方法时,该状态会被修改。如果多个线程调用同一个dateformat对象的方法,则一个线程可能会修改其他线程所需的状态,结果是某些线程获得的结果可能是错误的。内部状态损坏导致错误输出的可能性使该类不是线程安全的。
有多种方法可以解决此问题。您可以让应用程序中需要简单日期格式对象的每个位置在每次需要时实例化一个新对象,您可以创建一个包含简单日期格式对象的 ThreadLocal,以便程序的每个线程都可以访问自己的副本(因此每个线程只需要创建一个),您可以使用不保留状态的简单日期格式的替代方法, 或者,您可以使用 synced
执行锁定,以便一次只有一个线程可以访问 dateFormat 对象。
锁定不一定是最佳方法,最好尽可能避免共享可变状态。这就是为什么在Java 8中他们引入了一个不保持可变状态的日期格式化程序。
< code>synchronized关键字是限制访问方法或代码块的一种方式,这样线程不安全的数据就不会被破坏。此关键字通过要求线程在进入方法或块之前必须获得对特定锁(如果synchronized位于实例方法上,则为对象实例;如果synchronized位于静态方法上,则为类实例;如果使用synchronized块,则为指定锁)的独占访问权来保护方法或块,同时提供内存可见性,以便线程不会看到过时数据。
最近我在读一些关于java并发的书。关于线程安全,如果不可能使一个类变为inmutable,那么可以通过同步它的数据来确保线程安全。 下面的类显然不是线程安全的 然后我可以同步写,但它不会保持线程安全 因为我不仅需要同步写入,还需要同步读取 现在的问题是,通过使用易失性,我可以保证其他线程会看到更新的值,所以这让我认为这个类应该是线程安全的 最后一个类线程安全吗??
问题内容: 在阅读了“ 实践中的Java并发 ”和“ 实践OSGI ”之后,我发现了一个非常有趣的特定主题。安全发布。以下是来自JCIP的内容: 为了安全地发布对象,必须同时使对该对象的引用和该对象的状态对其他线程可见。可以通过以下方式安全地发布正确构造的对象: 从静态初始化程序初始化对象引用。 将对它的引用存储到可变字段中。 将对它的引用存储到最终字段中。 将对它的引用存储到由(同步)锁适当保护
我有一个从Rabbit接收消息的应用程序。当收到一条消息时,它会对它进行处理,然后在完成时执行ACK。应用程序可以在一个固定的线程池中同时处理2个项目,有2个线程。Rabbit的QOS预取设置为2,因为我不想在一个时间框架内给应用提供超过它所能处理的内容。 现在,我的消费者的handleDelivery执行以下操作: 此时,您已经发现TestWrapperThread将调用作为最后一个操作。 根据
问题内容: HttpUrlConnection线程安全吗?即,如果我有一个连接到服务器的HttpConnection实例,并且该实例被不同的线程使用(例如,尝试同时发送POST),HttpUrlConnection将如何处理这种情况?a)他们将串行发送POST,还是b)第一个线程发送POST,获取响应,然后第二个线程发送POST?如果它们以串行方式发送POST,则意味着到同一tcp连接的多个活动P
假设我有一个Executors静态工厂方法的ExecutorService实例。 如果我从某个线程提交了一个调用,其中RetVal不是线程安全的本地实例化对象,那么当我从同一个线程获得()它时,我需要担心retvals的完整性吗?人们说局部变量是线程安全的,但我不确定当您返回一个本地实例化的对象并从其他线程接收它时,它是否适用。 下面是我的定制实现,我只是为了测试。您可以忽略EType枚举。
在PHP初期,是作为单进程的CGI来运行的,所以并没有考虑线程安全问题。 我们可以随意的在全局作用域中设置变量并在程序中对他进行修改、访问,内核申请的资源如果没有正确的释放, 也会在CGI进程结束后自动地被清理干净。 后来,php被作为apache多进程模式下的一个模块运行,但是这仍然把php局限在一个进程里, 我们设置的全局变量,只要在每个请求之前将其正确的初始化,并在每个请求之后正确的清理干净