Java 学习线程

Java 学习线程,java,multithreading,Java,Multithreading,我写了一个简单的程序,打算启动几个线程。然后,线程应该从整数数组中选择一个整数n,使用它等待n,并返回线程等待返回数组的时间t 如果一个线程完成了它的任务,它应该选择下一个尚未分配给另一个线程的线程。 当然:数组中的顺序必须保持,以便整数和结果匹配 就我所见,我的代码运行平稳。 但是,我使用了一行代码块,我觉得特别不满意,希望有一个好方法可以在不做太多更改的情况下解决这个问题: while(Thread.activeCount() != 1); // first evil line 我有点滥用

我写了一个简单的程序,打算启动几个线程。然后,线程应该从整数数组中选择一个整数n,使用它等待n,并返回线程等待返回数组的时间t

如果一个线程完成了它的任务,它应该选择下一个尚未分配给另一个线程的线程。
当然:数组中的顺序必须保持,以便整数和结果匹配

就我所见,我的代码运行平稳。 但是,我使用了一行代码块,我觉得特别不满意,希望有一个好方法可以在不做太多更改的情况下解决这个问题:

while(Thread.activeCount() != 1); // first evil line
我有点滥用这一行,以确保我的所有线程都完成了所有任务,然后才访问我的数组和结果。我想这样做是为了防止错误值,比如0.0,空指针异常。。。等等(简而言之,任何可能导致应用程序实际使用崩溃的内容) 任何形式的建设性帮助都是非常感谢的。我也不确定,如果我的代码对于线程的非常长的任务数组仍然平稳运行,例如,结果不再匹配整数的顺序

任何有建设性的帮助都将不胜感激

头等舱:

public class ThreadArrayWriterTest {

    int[] repitions;
    int len = 0;
    double[] timeConsumed;

    public boolean finished() {
        synchronized (repitions) {
            return len <= 0;
        }
    }

    public ThreadArrayWriterTest(int[] repitions) {
        this.repitions = repitions;
        this.len = repitions.length;
        timeConsumed = new double[this.len];
    }

    public double[] returnTimes(int[] repititions, int numOfThreads, TimeConsumer timeConsumer) {

        for (int i = 0; i < numOfThreads; i++) {
            new Thread() {
                public void run() {
                    while (!finished()) {
                        len--;
                        timeConsumed[len] = timeConsumer.returnTimeConsumed(repititions[len]);
                    }
                }

            }.start();
        }
        while (Thread.activeCount() != 1) // first evil line
            ;
        return timeConsumed;
    }

    public static void main(String[] args) {
        long begin = System.currentTimeMillis();
        int[] repitions = { 3, 1, 3, 1, 2, 1, 3, 3, 3 };
        int numberOfThreads = 10;

        ThreadArrayWriterTest t = new ThreadArrayWriterTest(repitions);
        double[] times = t.returnTimes(repitions, numberOfThreads, new TimeConsumer());
        for (double d : times) {
            System.out.println(d);
        }
        long end = System.currentTimeMillis();
        System.out.println("Total time of execution: " + (end - begin));
    }
}
公共类ThreadArrayWriterTest{
国际代表;
int len=0;
双[]时间消耗;
公共布尔完成(){
已同步(重复){

return len等待所有线程完成的最简单方法是保留它们的集合,然后依次对每个线程调用
Thread.join()

等待所有线程完成的最简单方法是保留它们的集合,然后依次对每个线程调用
Thread.join()

除了
.join()
您可以使用来管理线程池

提供管理终止和终止方法的方法的执行者 这可以为跟踪一个或多个项目的进展创造未来 异步任务

ExecutorService可能会被关闭,这将导致它拒绝新服务 任务。提供了两种不同的方法来关闭 ExecutorService.shutdown()方法将允许以前提交的 终止之前要执行的任务,而shutdownNow()方法 阻止当前正在等待的任务启动和尝试停止 执行任务。终止后,执行者没有活动任务 正在执行,没有等待执行的任务,也不能创建新任务 已提交。应关闭未使用的ExecutorService以允许 资源回收

方法submit扩展了基本方法Executor.execute(Runnable)by 创建并返回可用于取消执行的未来 和/或等待完成。方法invokeAny和invokeAll执行 最常用的批量执行形式是执行 收集任务,然后等待至少一个或全部任务完成 完成

ExecutorService ExecutorService=Executors.newFixedThreadPool(最大线程数);
CompletionService CompletionService=新的ExecutionCompletionService(ExecutionService);
for(int i=0;i
另外,请看一看

除了可以用来管理线程池的
.join()

提供管理终止和终止方法的方法的执行者 这可以为跟踪一个或多个项目的进展创造未来 异步任务

ExecutorService可能会被关闭,这将导致它拒绝新服务 任务。提供了两种不同的方法来关闭 ExecutorService.shutdown()方法将允许以前提交的 终止之前要执行的任务,而shutdownNow()方法 阻止当前正在等待的任务启动和尝试停止 执行任务。终止后,执行者没有活动任务 正在执行,没有等待执行的任务,也不能创建新任务 已提交。应关闭未使用的ExecutorService以允许 资源回收

方法submit扩展了基本方法Executor.execute(Runnable)by 创建并返回可用于取消执行的未来 和/或等待完成。方法invokeAny和invokeAll执行 最常用的批量执行形式是执行 收集任务,然后等待至少一个或全部任务完成 完成

ExecutorService ExecutorService=Executors.newFixedThreadPool(最大线程数);
CompletionService CompletionService=新的ExecutionCompletionService(ExecutionService);
for(int i=0;i

另外,请看一看

,因为java在包中提供了更高级的线程API,所以您应该了解它,它简化了线程管理机制

简单地解决你的问题

  • 使用Executors API创建线程池

    static ExecutorService  newFixedThreadPool(int nThreads)
    
    创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程

  • 用于等待所有任务完成

    示例代码:

    ExecutorService service = Executors.newFixedThreadPool(10);
    
    List<MyCallable> futureList = new ArrayList<MyCallable>();
    for ( int i=0; i<12; i++){
        MyCallable myCallable = new MyCallable((long)i);
        futureList.add(myCallable);
    }
    System.out.println("Start");
    try{
        List<Future<Long>> futures = service.invokeAll(futureList);  
        for(Future<Long> future : futures){
            try{
                System.out.println("future.isDone = " + future.isDone());
                System.out.println("future: call ="+future.get());
            }
            catch(Exception err1){
                err1.printStackTrace();
            }
        }
    }catch(Exception err){
        err.printStackTrace();
    }
    service.shutdown();
    
    ExecutorService=Executors.newFixedThreadPool(10);
    List futureList=新建ArrayList();
    
    对于(inti=0;i,由于java在包中提供了更高级的线程API,您应该研究一下,这简化了线程管理机制

    简单地解决你的问题

  • 使用Executors API创建线程池

    static ExecutorService  newFixedThreadPool(int nThreads)
    
    创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程

  • 用于等待所有任务完成

    示例代码:

    ExecutorService service = Executors.newFixedThreadPool(10);
    
    List<MyCallable> futureList = new ArrayList<MyCallable>();
    for ( int i=0; i<12; i++){
        MyCallable myCallable = new MyCallable((long)i);
        futureList.add(myCallable);
    }
    System.out.println("Start");
    try{
        List<Future<Long>> futures = service.invokeAll(futureList);  
        for(Future<Long> future : futures){
            try{
                System.out.println("future.isDone = " + future.isDone());
                System.out.println("future: call ="+future.get());
            }
            catch(Exception err1){
                err1.printStackTrace();
            }
        }
    }catch(Exception err){
        err.printStackTrace();
    }
    service.shutdown();
    
    ExecutorService=Executors.newFixedThreadPool(10);
    List futureList=新建ArrayList();
    对于(int i=0;i