【问题标题】:Multithreading || Java多线程 ||爪哇
【发布时间】:2016-02-16 08:16:01
【问题描述】:

我有一个程序如下。我希望三个并发线程使用线程同步将不同的字符串添加到infiList ("This", "is", "infinite")。

例如,我还想附加某些线程;

  • 如果infiList 中的最后一个单词当前是“This”,则线程应将单词“is”附加到infiList。

  • 如果infiList 中的最后一个单词当前是“is”,则线程应将单词“infinite”附加到infiList。

  • 如果infiList 中的最后一个单词当前是“infinite”,或者如果infiList 仍然为空,则线程应将单词“This”附加到infiList。

  • 在任何时候,infiList 应仅在列表开头或紧接在出现“infinite”之后包含“This”,“is”应仅出现在列表中紧接在“This”之后,并且一个“无限”应该 仅在“是”之后直接出现。

感谢任何有关如何执行此操作的帮助。

import java.util.ArrayList;

public class Multithreading implements Runnable {

public static ArrayList<String> infiList = new ArrayList<>();

@Override
public void run() {
    for (int i=0; i<100; i++) {
        String s = null;
        synchronized (infiList) {
            if(infiList.isEmpty())
                infiList.add("This");
            else
            {
                s = infiList.get(infiList.size()-1);

            if(s.equals("This"))
                infiList.add("is");
            else if(s.equals("is"))
                infiList.add("infinite");
            else if(s.equals("infinite"))
                infiList.add("This");
            }
        }
    }
}

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();

}
}

【问题讨论】:

    标签: java string multithreading loops arraylist


    【解决方案1】:

    非常天真地快速解决了这个问题。 Synchronized 将在 arraylist 上获得一个锁,检查元素并根据您的规则插入它。但是由于您的逻辑取决于最后一个元素,同时将元素添加到数组中同时保持元素的顺序,这实际上不是多线程的,而是一个顺序程序。

    这仅仅是因为,当多线程程序运行时,您并不关心顺序,因为您永远无法保证它。在大多数情况下,您将进入分而治之风格的算法,其中算法将被分成几部分并按部分计算。

    @Override
    public void run() {
        for(int i = 0; i < 100; i++) {
            String s = null;
            synchronized (infiList) {
                if(infiList.isEmpty())
                    infiList.add("This");
                else
                {
                    s = infiList.get(infiList.size()-1);
    
                if(s.equals("This"))
                    infiList.add("is");
                else if(s.equals("is"))
                    infiList.add("infinite");
                else if(s.equals("infinite"))
                    infiList.add("This");
                }
            }
        }
    }
    

    如何利用多线程

    如果我们在另一种情况下查看您的示例,您需要在将某些内容放入数组之前进行计算。这可能会导致更好地利用多线程性能。

    @Override
    public void run() {
        while (true) {
            String s = null;
    
            CalculateSomethingBig();
    
            synchronized (infiList) {
                ...
            }
        }
    }
    

    如果我们考虑一下,主要运行时位于CalculateSomethingBig() 中,现在这将利用更多的计算机多任务处理能力,因为更多的线程将使用时间来计算和利用处理能力,然后等待锁被释放。

    如何获得输出

        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();
    
        for(String s : infiList)
            System.out.println(s);
    }
    

    【讨论】:

    • 当我尝试运行它时,我收到多个错误"Exception in thread "Thread-0" java.lang.NullPointerException at Multithreading.run(Multithreading.java:17) at java.lang.Thread.run(Unknown Source)"
    • 但是你的循环将永远运行......或者可能无限:)
    • 不使用 while(true) 实现它的最佳方法是什么?
    • 做一个运行 100 次或类似的 for 循环 :)
    • 然后打印出来?看来你的 Java 技能还没有达到我建议玩线程的水平。
    猜你喜欢
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    相关资源
    最近更新 更多