线程安全与同步

我是Java的新手。我对Threadsafe和synced有点困惑。线程安全意味着方法或类实例可以同时由多个线程使用,而不会发生任何问题。其中,“已同步”表示一次只能运行一个线程。

那么它们是如何相互关联的呢?


答案 1

Java 并发实践中给出的线程安全定义是:

如果从多个线程访问类时该类的行为正确,则无论运行时环境对这些线程的执行进行调度或交错如何,并且调用代码没有额外的同步或其他协调,则该类是线程安全的。

例如,java.text.SimpleDateFormat 对象具有内部可变状态,在调用解析或格式化方法时会修改该状态。如果多个线程调用同一 dateformat 对象的方法,则线程有可能修改其他线程所需的状态,从而导致某些线程获得的结果可能出错。内部状态损坏导致输出错误的可能性使此类不是线程安全的。

有多种方法可以解决此问题。你可以让应用程序中每个需要 SimpleDateFormat 对象的地方在每次需要一个对象时实例化一个新的对象,你可以让一个 ThreadLocal 保存一个 SimpleDateFormat 对象,以便程序的每个线程都可以访问它自己的副本(所以每个线程只需要创建一个),你可以使用不保留状态的 SimpleDateFormat 的替代方案, 或者您可以使用 进行锁定,以便一次只有一个线程可以访问 dateFormat 对象。synchronized

锁定不一定是最好的方法,尽可能避免共享可变状态是最好的。这就是为什么在Java 8中他们引入了一个不保持可变状态的日期格式化程序。

关键字是限制对方法或代码块的访问的一种方法,否则线程不安全的数据不会损坏。此关键字通过要求线程必须获取对某个锁(如果同步的对象实例位于实例方法上,或者类实例,如果同步在静态方法上,或者如果使用同步块,则为指定的锁)才能进入方法或块来保护方法或块, 同时提供内存可见性,以便线程不会看到过时的数据。synchronized


答案 2

线程安全是程序的一种所需行为,其中块可帮助您实现该行为。还有其他方法可以获得线程安全,例如不可变的类/对象。希望这有帮助。synchronized