如何在Java中使方法线程安全?

236 阅读2分钟

在优锐课的java学习中,讨论了关于企业职场面试问题。一起来get

以下方法是线程安全的吗?

如何使其成为线程安全的?

class MyCounter {	private static int counter = 0; 	public static int getCount() {		return counter++;	}}

这篇文章解释了Google和许多公司提出的一般面试问题。 它是低级的,与如何设计并发程序无关。

首先,答案是否定的。该方法不是线程安全的,因为Counter ++操作不是原子操作,这意味着它包含多个原子操作。 在这种情况下,一个正在访问值,另一个正在将值增加一个。


当线程1在t1访问该方法时,线程2可能无法使用该方法完成。 因此,返回到线程1的值是尚未增加的值。

使方法成为线程安全的-方法1

将同步添加到此方法将使其具有线程安全性。当将同步添加到静态方法时,Class对象是被锁定的对象。

标记是否足够同步?答案是肯定的。

class MyCounter {	private static int counter = 0; 	public static synchronized int getCount() {		return counter++;	}}

如果该方法不是静态的,则添加同步关键字将同步该类的实例而不是Class对象的实例。

使方法成为线程安全的-方法2

在这个特定的反例中,我们实际上可以通过使用来自包“ java.util.concurrent.atomic”的AtomicInteger来使++++原子化。

import java.util.concurrent.atomic.AtomicInteger; public class MyCounter {	private static AtomicInteger counter = new AtomicInteger(0); 	public static int getCount() {		return counter.getAndIncrement();	}}

有关线程安全的其他一些有用事实

局部变量在Java中是线程安全的。

每个线程都有自己的堆栈。两个不同的线程永远不会共享同一堆栈。方法中定义的所有局部变量都将在堆栈中分配内存。当前线程完成方法执行后,将删除堆栈框架。