gpt4 book ai didi

java - 通过线程构造函数按引用分配的列表变量不起作用

转载 作者:行者123 更新时间:2023-12-01 23:45:06 24 4
gpt4 key购买 nike

我正在通过一个线程的构造函数初始化我的线程之一的类变量我的服务类别如下:

ProcessMediaThread pThread = new ProcessMediaThread(listMediaPath, mediaType);
pThread.start();

其中listMediaPathArrayList<String>();对象。
ProcessMediaThread 类内部:

public class ProcessMediaThread extends Thread 
{
private List<String> absoluteMediaPath= new ArrayList<String>();
private String mediaType;
public ProcessMediaThread(List<String> absoluteMediaPathList, String mediaType)
{
this.absoluteMediaPath = absoluteMediaPathList;
this.mediaType= mediaType;
}

我的重写run()方法:

@Override
public void run()
{
if(mediaType.equals(MediaType.PHOTO)) //<- mediaType value is retained..
{
for(int i=0;i<absoluteMediaPath.size();i++) // <- here absoluteMediaPath is empty..!!
{
//...
}

我的一位 friend 建议我在构造函数级别遵循不同的方法:

this.absoluteMediaPath.addAll(absoluteMediaPathList);

有效..!!
任何人都可以建议问题到底出在哪里以及addAll(Collection<? extends E> c);是什么?在做什么?

最佳答案

如果您使用addAll,则会将列表的内容复制到ProcessMediaThread 内的单独集合中。这意味着外部对其进行的更改不会影响它。例如,考虑:

ProcessMediaThread pThread = new ProcessMediaThread(listMediaPath, mediaType);
pThread.start();
listMediaPath.clear();

使用您当前的代码,您的新线程可能会看到一个空集合 - 或者它可能会看到一个包含数据的集合,然后突然被清除。这不是一个好的情况。此外,ArrayList 不是线程安全的,因此在一个线程中修改它并在另一个线程中读取它很可能会导致问题。

当您创建私有(private)副本(使用addAll)时,上面第三行的clear()将不起作用,因为它不会影响线程正在使用的同一个集合。

其他几点:

  • 我建议您单独实现Runnable,而不是扩展Thread。然后,您可以将 Runnable 实例传递给 Thread 构造函数;这可以更好地分离“在新线程上运行任务的机制”和“要运行的任务”。
  • 除非您确实在循环中需要 i 的值,否则您可以使用:

    for (String mediaPath : absoluteMediaPath) {
    ...
    }
  • 调用 addAll 的替代方法是仅使用 ArrayList(Collection) 构造函数在构造函数中初始化集合。

因此,将所有这些放在一起,我会将您的类(class)更改为:

public class MediaProcessor implements Runnable {
private final List<String> absoluteMediaPath;
private final String mediaType;

public MediaProcessor(List<String> absoluteMediaPathList, String mediaType) {
this.absoluteMediaPath = new ArrayList(absoluteMediaPathList);
this.mediaType = mediaType;
}

@Override
public void run() {
if (mediaType.equals(MediaType.PHOTO)) {
for (String mediaPath : absoluteMediaPath) {
...
}
}
}
}

...

Thread thread = new Thread(new MediaProcessor(listMediaPath, mediaType));
thread.start();

关于java - 通过线程构造函数按引用分配的列表变量不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17206070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com