简体   繁体   English

提交给固定线程池ExecutorService的任务是线程安全的吗?

[英]Tasks submitted to Fixed threadpool ExecutorService are threadsafe?

The tasks submitted uses resource beans from a spring container. 提交的任务使用来自Spring容器的资源bean。 Are the methods in the beans thread safe when accessed by concurrent threads of a executor service? 当由执行程序服务的并发线程访问时,bean线程中的方法是否安全?

They aren't thread-safe by definition. 根据定义,它们不是线程安全的。 If your Spring beans are immutable, stateless or properly synchronized (99% of the cases) they are thread safe. 如果您的Spring bean是不可变的,无状态的或正确同步的(99%的情况),则它们是线程安全的。 Here are few examples of thread-safe Spring beans: 以下是线程安全的Spring Bean的一些示例:

Only final fields: final字段:

public class ImmutableService {

    private final Dependency dep;

    @Autowired
    public StatelessService(Dependency dep) {
        this.dep = dep;
    }

    public Foo foo() {
        return dep.foo();
    }

}

Field is modified only during creation, effectively final: 仅在创建期间修改字段,实际上是最终的:

public class EffectivelyImmutableService {

    @Autowired
    private final Dependency dep;

    public Foo foo() {
        return dep.foo();
    }

}

No state, typical utility class: 无状态,典型实用程序类:

public class StatelessService {

    public Foo foo() {
        return new Foo();
    }

}

Non-atomic operations are synchronized : 非原子操作是synchronized

public class SynchronizedService {

    private int counter;

    public synchronized Foo foo() {
        return new Foo(counter++);
    }

}

AtomicInteger to avoid explicit synchronization (field is final , but the object isn't): AtomicInteger避免显式同步(field是final ,但对象不是):

public class AtomicService {

    private final AtomicInteger counter = new AtomicInteger();

    public Foo foo() {
        return new Foo(counter.incrementAndGet());
    }

}

Note that this rule applies to all use-cases, not only to tasks using Spring beans in thread pool. 请注意,此规则适用于所有用例,不仅适用于在线程池中使用Spring Bean的任务。 For instance if your servlets/controllers use Spring beans, they have to be thread safe as well. 例如,如果您的servlet /控制器使用Spring bean,那么它们也必须是线程安全的。

If you were to manually start two threads accessing these beans, would the access be threadsafe then? 如果要手动启动两个线程访问这些bean,那么访问是否是线程安全的? An executor service does no magic and does not change anything about the code running in its threads. 执行程序服务无可厚非,并且不会更改其线程中运行的代码。 If accessing the beans is not threadsafe from two manually started threads, it's not threadsafe when the code is executed by threads managed by an Executor either. 如果从两个手动启动的线程访问bean都不是线程安全的,则当代码由执行程序管理的线程执行时,也不是线程安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM