java - 多线程中的实例变量行为

标签 java spring multithreading

我正在尝试运行一个具有 4 个线程的程序。我想了解线程中实例变量的行为。在此我需要将一个值传递给该方法。因此,我这样做是为了传递该值并将其用于进一步处理。

@Component
class ThreadExample implements Runnable
{
    String file;

    public void setFile(String file)
    {
       this.file = file;
    }
    @override
    public void run()
    {
       readFile(file);
    }
    public void readFile(String fileName)
    {  
        //logic for reading file
    }
}

@component
class ThreadCall
{
    @Autowired
    ThreadExample ex;

     public void testThread()
     {
        ExecutorService executor2 = Executors.newFixedThreadPool(4);
        getFiles()
          .stream()
          .forEach(f-> {
               ex.setFile(f);
               executor2.submit(ex);                             
           });
     }

}

getFiles() API 返回文件名列表。我正在尝试在 Spring 中执行此操作。 这里,4个线程将同时工作。对象ex Autowiring 的,因此它只会被实例化一次。

file变量值会如何影响?

我想,一个线程将尝试通过 setFile(file) 设置文件,并且在 readFile 中使用它之前,它会被另一个线程更改。

如何解决这个问题?多线程中如何传值? 如果我将 'file' 设置为 volatile ,我的问题会得到解决吗?

最佳答案

这里:

@Component
class ThreadExample implements Runnable
{
    String file;

    public void setFile(String file)

还有

Object ex is autowired so it will be instantiated only once.

那是行不通的。你有:

executor2.submit(ex);      

您将相同对象传递给多个任务,这些任务应该并行执行特定的操作。更糟糕的是,您将不同的值放入该单个对象中,并以某种方式神奇地期望每个任务准确地看到您希望它看到的值。会发生什么:这些事情发生在不同的线程上,因此结果(可能)完全随机,也称为不确定性。

长话短说:当您需要完成多个“事情”时,随着时间的推移,您将无法使用“单例”容器来分派(dispatch)参数。 volatile 对此没有帮助,一点也没有。

答案是:为了使其工作,ThreadExample 不能是“单例”,因此将其变成单例的 @Component 注释必须消失。如果这样做与您的其他设计理念“冲突”,那么您必须退后一步并重新设计您的设计。

关于java - 多线程中的实例变量行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54516563/

相关文章:

Spring安全认证: get username without SPRING_SECURITY_LAST_USERNAME

java - 包是否需要放在 jar 中才能用于 ant 构建脚本

java - Jackson 无限递归处理查询

java - 具有默认系统身份验证/用户的 SecurityContext

java - 不同模块的注释 spring 上下文的问题

c# - 在 foreach 循环中启动任务使用最后一项的值

JAVA同步块(synchronized block)在多线程环境中不起作用

ios - NSoperationQueue阻塞主线程

java - Spring Security jwt单元测试

Java反序列化和ArrayList奇怪的异常