如何在线程之间转移控制

时间:2014-02-24 16:10:28

标签: java multithreading

我有一个问题,在谷歌搜索了很长一段时间之后我找不到它的答案。 我打算创建一个浏览器应用程序。我想要的是,当主方法运行时,我认为它是主浏览器应用程序,用户现在可以选择打开多个选项卡。每次打开选项卡时都会启动一个线程,当主应用程序关闭时,所有选项卡都将关闭。每个选项卡(线程)将独立运行,用户可以选择切换选项卡,前一个选项卡继续执行它的操作当用户在新选项卡中工作时,用户可以根据需要打开任意数量的选项卡。 这是我的代码:

import java.util.Scanner;

public class mainClass 
{
    /**
     * @param args
     */
    public static void main(String[] args) 
    {
        Scanner in = new Scanner(System.in);

        String input="abc";
        String check="true";

        while (check=="true")
        {
            System.out.println("if you want to open new tab write yes");
            input=in.nextLine();
            if (input.equals("yes"))
            {
                System.out.println("if check");
                Thread tab = new myThread();
                tab.start();
                check="true";
            }
            else
            {
                check="false";
                System.out.println("else check");
            }
        }
        return;
    }
}

public class myThread extends Thread 
{
    public myThread()
    {
        setDaemon(true);                                                                                                        
    }

    public void run()
    {
            Scanner in = new Scanner(System.in);

        System.out.println("one thread started");

            System.out.println("enter url to search\n");

            String input=in.nextLine();

    }
}

我的问题是,当用户希望打开线程时,它会打开,完成其任务,而不是等待从用户那里获取输入,然后返回主线程。我想要的是用户应该可以选择在标签之间切换。当用户打开一个标签时,即使他什么也没做,当他想要切换到另一个标签时,他仍然会停留在该标签上。 我如何完全控制一个线程或如何睡眠()主线程,直到用户正在处理一个新线程,当用户希望回到主线程,他可以做到这一点?是可能的吗? / p>

2 个答案:

答案 0 :(得分:0)

首先,代码中的一个基本错误是check=="true"条件总是false

您可以将其更改为check.equals("true")来快速解决,但您也可以正确修复它:

  • String check更改为boolean check
  • "false"更改为false
  • "true"更改为true

其次,这是我对一般线程方案的建议:

第1步 - 不要扩展Thread类,而是实施Runnable界面:

public class MyClass implements Runnable
{
    public MyClass(String input)
    {
        this.input = input;
    }

    public String getOutput()
    {
        return output;
    }

    public void run()
    {
        ...
        output = ...;
    }

    private String input  = null;
    private String output = null;
}

步骤#2 - 保存列表中的所有线程,启动每个线程,然后加入每个线程:

public static ArrayList<String> run(ArrayList<String> inputs,long maxMillisPerThread)
{
    ArrayList<MyClass> myObjects = new ArrayList<MyClass>();
    ArrayList<Thread>  threads   = new ArrayList<Thread>();
    ArrayList<String>  outputs   = new ArrayList<String>();
    for (String input : inputs)
    {
        MyClass myObject = new MyClass(input);
        Thread  thread   = new Thread(myObject);
        myObjects.add(myObject);
        threads.add(thread);
        thread.start();
    }
    for (Thread thread : threads)
    {
        try
        {
            thread.join(maxMillisPerThread);
        }
        catch (Exception error)
        {
        }
    }
    for (MyClass myObject : myObjects)
    {
        outputs.add(myObject.getOutput());
    }
    return outputs;
}

步骤#3 - 为每个线程创建所需的输入,并将其传递给上面的函数。例如:

ArrayList<String> inputs = new ArrayList<String>();
for (int i=0; i<...; i++)
    inputs.add(...);

ArrayList<String> outputs = run(inputs,3000);
for (String output : outputs)
    System.out.println(output);

答案 1 :(得分:0)

您将始终拥有一个“主”线程,这通常是唯一将用于UI操作(绘制组件,处理用户输入等)的线程。您必须将此线程用于所有选项卡,至少对于UI操作而言。

你可以拥有的是每个标签的一个主题,它将用于你必须为这个标签做的任何计算操作(即除了绘制到屏幕之外的几乎所有内容)。您不需要在线程之间“切换”,它们并发运行,您只需要主线程和这些选项卡线程之间的某种通信机制。用于此通信的内容主要取决于您使用的UI堆栈(swing?android?other?)。

主线程总是有某种运行循环机制(由GUI工具包提供),您可以使用它来发布要在此线程上运行的事件。在java中有线程通信实用程序,但是当你谈到UI和选项卡时,你真的需要知道你正在开发哪个工具包并使用它自己的机制。例如,对于Swing,您可以使用SwingWorkerSwingUtilities#invokeLater