【问题标题】:Java Multithreading & Adding to Static FieldJava 多线程和添加到静态字段
【发布时间】:2016-02-16 07:18:08
【问题描述】:

我想编写一个程序,在 main 方法中运行 3 个并发线程,该方法使用无限循环将字词添加到类型为 ArrayList<String> 的静态字段 infiList

我知道如何创建线程并运行它们,但我不知道如何将它们添加到infiList。任何帮助将不胜感激:)

import java.util.ArrayList;

public class Multithreading implements Runnable {

public Multithreading () {
    //
}

// Implement the run method in Runnable
public void run() {
// Tell system how to run custom thread

}


public static int infiList(ArrayList<String>) {

    return t1;
}

public static void main (String args[]) {

    // Create an instance of the class
    Multithreading task = new Multithreading();

    // Create a thread
    Thread t1 = new Thread(task);
    Thread t2 = new Thread(task);
    Thread t3 = new Thread(task);

    // Start a thread
    t1.start();
    t2.start();
    t3.start();
 }

}

【问题讨论】:

  • “我知道如何创建线程并运行它们”我希望你意识到,在你的代码中你没有启动一个Thread?顺便提一句。如果你实现Runnable,你需要覆盖run-方法
  • 什么是t1?你的代码没有意义,你为什么要发布一些甚至无法编译的东西?

标签: java arrays multithreading loops static


【解决方案1】:

如果您希望您的线程添加到列表中,那么您必须在线程中完成工作并在线程运行时添加单词。通过无限循环,我想你的意思是一个while循环,所以你需要创建一个线程类来完成工作并在完成时返回字符串。获取返回的字符串并将其添加到数组中。

从您的代码的外观来看,我认为您没有正确实现线程。声明 Runnable 只是意味着你有一个 run 方法,而你没有。实现线程只有两种方式。 1. 使用 Thread 类或扩展线程的类 2. 实现 SwingWorker 类。

https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

【讨论】:

    【解决方案2】:

    解决方法如下:

    import java.util.ArrayList;
    
    public class Multithreading implements Runnable {
    
    public static ArrayList<String> infiList = new ArrayList<>();
    
    @Override
    public void run() {
        while (true) {
            infiList.add("testing");
            System.out.print("string added");
        }
    }
    
    public static void main (String args[]) {
        // Create three concurrent threads
        new Thread(new Multithreading()).start();
        new Thread(new Multithreading()).start();
        new Thread(new Multithreading()).start();
    
    }
    }
    

    当然同步会有问题。所以,请确保你做得正确。

    【讨论】:

    • 我会将synchronized(infiList){...} 添加到循环中。
    【解决方案3】:

    您在“运行”方法中定义线程将执行的操作,在其中您必须使用单词更新静态列表。

    由于并发问题,使用带有线程的静态列表是一个非常糟糕的主意:线程将更新相同的内存位置并显示覆盖,使用

    Collections.synchronizedList
    

    当你创建列表时

    【讨论】:

    • “静态列表”没有任何意义。列表不能是静态的。只有 变量 可以是静态的,但在 Java 中,变量永远不能保存 List;它只能保存对列表的引用。当然,如果只有一个变量引用 List,这种区别并不重要,但在 Java 中,多个变量引用同一个对象是可能的(并且经常有用)。
    • “使用带有线程的 [共享] 列表是一个非常糟糕的主意。”为什么?除了共享对象之外,线程之间不可能相互通信,线程共享一个List的用例很多。
    • “使用Collections.synchronizedList。” Collections.synchronizedList(l)返回的对象一个List。也就是说,它是一个实现List接口的对象。
    • 当我说静态列表时,我的意思是:私有静态最终列表> 列表。也就是说,List 的静态实例(Arraylist 或任何你想要的),我认为很清楚,不需要规范。正如 Orla 所说,使用静态(不是共享的,共享列表不必是静态的,可以是成员类)是一个坏主意,因为线程并发。为避免这种情况,您必须使用 Collections.synchronizedList 或其他机制。事实上,结果是另一个列表,但是一个知道并发的列表,这就是重点。感谢您的cmets,但我认为不需要
    • 我同意,完全清楚你在说什么,我的所有同事也一样清楚,但两者之间的区别对于在这里提问的新手来说,实例和对象根本不明显。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多