Java 线程模板

Java 线程模板,java,multithreading,thread-safety,threadpool,Java,Multithreading,Thread Safety,Threadpool,好的,我有一个GUI Java应用程序,它允许用户选择并启动5-500个软件设备,每个设备由一个线程表示。线程不断地用信息更新GUI 用户可以选择线程并暂停、恢复或终止它们 所有关于线程和线程池、中断、未来的信息。。。。我只是迷路了,想点燃互联网=) 我需要的是关于这方面的标准前进方向的明确指导。下面是我的线程类的概要 这是一个好的模板开始吗?如果没有,请编辑 package ACsimForm; import java.util.Random; import javax.swing.Swin

好的,我有一个GUI Java应用程序,它允许用户选择并启动5-500个软件设备,每个设备由一个线程表示。线程不断地用信息更新GUI

用户可以选择线程并暂停、恢复或终止它们

所有关于线程和线程池、中断、未来的信息。。。。我只是迷路了,想点燃互联网=)

我需要的是关于这方面的标准前进方向的明确指导。下面是我的线程类的概要

这是一个好的模板开始吗?如果没有,请编辑

package ACsimForm;

import java.util.Random;
import javax.swing.SwingUtilities;

public class Squeak implements Runnable {

    private  String name = "";  
    private  javax.swing.JTextArea ScroolPage;


        Squeak (String name, javax.swing.JTextArea MW )
        {
            this.value = true;
            this.name = name;
            this.ScroolPage = MW;
        }


         Random r = new Random();
         int num = r.nextInt(10-1) + 1;


    @Override
   public void run ()
        {                                 
            updateGUI("Thread "+name+" Loaded and Running");

            while(true)
            {
                updateGUI("New Data");

                try {                        
                      TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    updateGUI("Thread "+name+" Exiting!");
                    //return exits the method killing the thread
                    return;
                }                
            }                               
        }



 //this is the new way to communicate back to the GUI 
 private void updateGUI(final String foo) {
 SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
          ScroolPage.append(foo+"\r\n");      
        }
      });
    }
    }
以允许您从GUI终止或暂停/恢复线程的方式保持500个线程的最佳方式是什么


非常感谢。

我想你的
可运行的
就快到了。放弃神奇的
Boolean
标志的想法-这是一个充满问题的问题(请阅读
volatile
)。将中断本身用作信号。这就是为什么它会在那里

以下是具有任意数量
线程的系统的简单示例:

private static final class Printer implements Runnable {

    private final String printMe;

    public Printer(String printMe) {
        this.printMe = printMe;
    }

    @Override
    public void run() {
        while (true) {
            System.out.println(Thread.currentThread().getName() + "says: " + printMe);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException ex) {
                return;
            }
        }
    }
}

public static void main(String[] args) throws Exception {
    final ExecutorService executorService = Executors.newCachedThreadPool();
    final Map<Integer, Future<?>> futures = new HashMap<>();
    for (int i = 0; i < 10; ++i) {
        futures.put(i, executorService.submit(new Printer("Printer" + i)));
    }
    final Scanner scanner = new Scanner(System.in);
    while (true) {
        final String input = scanner.nextLine();
        if ("EXIT".equalsIgnoreCase(input)) {
            break;
        }
        final Integer threadToStop;
        try {
            threadToStop = Integer.parseInt(input);
        } catch (NumberFormatException ex) {
            System.out.println("Not a number");
            continue;
        }
        final Future<?> f = futures.remove(threadToStop);
        if (f == null) {
            System.out.println("Not a valid thread");
            continue;
        }
        f.cancel(true);
    }
    executorService.shutdownNow();
}
私有静态最终类打印机实现可运行{
私有最终字符串printMe;
公共打印机(字符串打印){
this.printMe=printMe;
}
@凌驾
公开募捐{
while(true){
System.out.println(Thread.currentThread().getName()+”表示:“+printMe”;
试一试{
时间单位。秒。睡眠(1);
}捕获(中断异常例外){
返回;
}
}
}
}
公共静态void main(字符串[]args)引发异常{
final ExecutorService ExecutorService=Executors.newCachedThreadPool();
最终映射f=未来。删除(threadToStop);
如果(f==null){
System.out.println(“不是有效线程”);
继续;
}
f、 取消(真);
}
executorService.shutdownNow();
}
我们使用
executor服务
来管理
线程
s-您不应该直接使用
线程
s,这再次受到地雷的困扰


ExecutorService
被要求运行任意数量的任务-您可以看到如何在
for
循环中添加任务

然后,
ExecutorService
为每个添加的任务返回一个
Future
——这些是任务的句柄。它们允许我们检查它们是否仍在进行/完成或遇到错误

我们
未来的
映射到任务名称,然后允许用户有选择地从输入中终止任务

你不能“暂停”和“恢复”一个
线程(当然你可以,但你最好不要担心这一点)。您只需在需要暂停任务时取消该任务,然后重新发出该任务以重新启动它。好的方面是,
ExecutorService
将回收运行任务的
线程
,这样您就不会失去性能

如果从多个线程向
Future
s的
Map
发出命令,则需要
ConcurrentHashMap


一个常见的陷阱是假设应用程序将在运行
ExecutorService
的情况下干净地退出。事实并非如此。
ExecutorService
生成非守护进程线程,因此应用程序在它们全部完成之前无法退出。你有两个选择;第一个是有点黑客行为-只需给
ExecutorService
你自己的
ThreadFactory
并创建
Thread
s守护进程,第二个是在你完成
ExecutorService
后关闭它,就像我在示例中所做的那样。

我认为你的
Runnable
差不多了。放弃神奇的
Boolean
标志的想法-这是一个充满问题的问题(请阅读
volatile
)。将中断本身用作信号。这就是为什么它会在那里

以下是具有任意数量
线程的系统的简单示例:

private static final class Printer implements Runnable {

    private final String printMe;

    public Printer(String printMe) {
        this.printMe = printMe;
    }

    @Override
    public void run() {
        while (true) {
            System.out.println(Thread.currentThread().getName() + "says: " + printMe);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException ex) {
                return;
            }
        }
    }
}

public static void main(String[] args) throws Exception {
    final ExecutorService executorService = Executors.newCachedThreadPool();
    final Map<Integer, Future<?>> futures = new HashMap<>();
    for (int i = 0; i < 10; ++i) {
        futures.put(i, executorService.submit(new Printer("Printer" + i)));
    }
    final Scanner scanner = new Scanner(System.in);
    while (true) {
        final String input = scanner.nextLine();
        if ("EXIT".equalsIgnoreCase(input)) {
            break;
        }
        final Integer threadToStop;
        try {
            threadToStop = Integer.parseInt(input);
        } catch (NumberFormatException ex) {
            System.out.println("Not a number");
            continue;
        }
        final Future<?> f = futures.remove(threadToStop);
        if (f == null) {
            System.out.println("Not a valid thread");
            continue;
        }
        f.cancel(true);
    }
    executorService.shutdownNow();
}
私有静态最终类打印机实现可运行{
私有最终字符串printMe;
公共打印机(字符串打印){
this.printMe=printMe;
}
@凌驾
公开募捐{
while(true){
System.out.println(Thread.currentThread().getName()+”表示:“+printMe”;
试一试{
时间单位。秒。睡眠(1);
}捕获(中断异常例外){
返回;
}
}
}
}
公共静态void main(字符串[]args)引发异常{
final ExecutorService ExecutorService=Executors.newCachedThreadPool();
最终映射f=未来。删除(threadToStop);
如果(f==null){
System.out.println(“不是有效线程”);
继续;
}
f、 取消(真);
}
executorService.shutdownNow();
}
我们使用
executor服务
来管理
线程
s-您不应该直接使用
线程
s,这再次受到地雷的困扰


ExecutorService
被要求运行任意数量的任务-您可以看到如何在
for
循环中添加任务

然后,
ExecutorService
为每个添加的任务返回一个
Future
——这些是任务的句柄。它们允许我们检查它们是否仍在进行/完成或遇到错误

我们
未来的
映射到任务名称,然后允许用户有选择地从输入中终止任务

你不能“暂停”和“恢复”一个
线程(当然你可以,但你最好不要担心这一点)。您只需在需要暂停任务时取消该任务,然后重新发出该任务以重新启动它。好的方面是,
ExecutorService
将回收运行任务的
线程
,这样您就不会失去性能

如果要从多个线程向
Future
s的
Map
发出命令,则需要