重学Java多线程

文章目录

  • 实现多线程的三种方法
  • RecursiveAction多线程框架
    • 作用:划分一个线程为多个线程并行
    • 举例
      • 寻找文件
      • 检索D盘下的文件个数
      • 求1到10000000的和

实现多线程的三种方法

  1. 继承Thread,并重写run方法,通过Thread1 thread1 = new Thread1("first thread");来使用
  2. 实现Runnable,并实现run方法,通过Thread thread = new Thread(new MyThread());来使用(MyThread实现了Runnable接口
  3. 实现Callable接口,和Runnable不同的是此方法又返回值
    声明方法和Runnable多封装了一步
class CallableThread implements Callable<String> {
    private Integer ticket = 10;

    @Override
    public String call() throws Exception {
        synchronized (this) {
            for (int i = 0; i < 10; i++) {
                System.out.println("zhgee" + i);
                System.out.println(ticket);
                ticket--;
                if (ticket < 0) {
                    break;
                }
            }
            return "票卖完了";
        }

    }
}
public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableThread callableThread=new CallableThread();
        CallableThread callableThread1=new CallableThread();
        FutureTask<String> futureTask=new FutureTask(callableThread);
        FutureTask<String> futureTask1=new FutureTask(callableThread1);
        new Thread(futureTask).start();
        new Thread(futureTask1).start();
        System.out.println(futureTask.get());
        System.out.println(futureTask1.get());

    }

}

RecursiveAction多线程框架

作用:划分一个线程为多个线程并行

举例

寻找文件

package com.scream.study.thread.ForkJoin.recursiveaction;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class FindFiles extends RecursiveAction {
    private File file;

    public FindFiles(File file) {
        this.file = file;
    }

    @Override
    protected void compute() {
        File[] fileList = file.listFiles();
        List<FindFiles> taskList = new ArrayList<>();
        if (fileList != null) {
            for (File eachFIle : fileList) {
                if (eachFIle.isDirectory()) {
                    FindFiles eachTask = new FindFiles(eachFIle);
                    taskList.add(eachTask);
                } else {
                    System.out.println(eachFIle.getAbsolutePath());
                }
            }
        }
        if(!taskList.isEmpty()){
            for (FindFiles eachTask : taskList) {
                eachTask.fork();
                eachTask.join();
            }
        }

    }

    public static void main(String[] args) {
        FindFiles task = new FindFiles(new File("D:\\腾讯"));
        ForkJoinPool poll = new ForkJoinPool();
        poll.execute(task);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("开始了");
        task.join();
        System.out.println("结束了");
    }
}

检索D盘下的文件个数

我们先将D盘下的所有文件夹检索出来,然后存入线程集合中,然后分别用你的cpu并行多个线程分别检索线程集合中存入的文件夹,如果是4线程就同时检索4个,检索完后自动取集合中剩余的线程

package com.scream.study.thread.ForkJoin.recursivetask;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class SumFiles extends RecursiveTask<Integer> {
    private File file;

    public SumFiles(File file) {
        this.file = file;
    }

    @Override
    protected Integer compute() {
        int count = 0;
        File[] fileList = file.listFiles();
        List<SumFiles> taskList = new ArrayList<>();
        if (fileList != null) {
            for (File eachFile : fileList) {
                if (eachFile.isDirectory()) {
                    taskList.add(new SumFiles(eachFile));
                } else {
                    count++;
                }
            }
        }
        if (!taskList.isEmpty()) {
            List<SumFiles> afterTaskList = (List<SumFiles>) invokeAll(taskList);
            for (SumFiles sumFiles : afterTaskList) {
                sumFiles.fork();
                count += sumFiles.join();
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int result = 0;
        File file = new File("D:\\");
        Long start = System.currentTimeMillis();
        SumFiles sumFiles = new SumFiles(file);
        ForkJoinPool poll = new ForkJoinPool();
        poll.invoke(sumFiles);
        result = sumFiles.join();
        Long end = System.currentTimeMillis();
        System.out.println(result + "共用时" + (end - start) + "毫秒");


        start = System.currentTimeMillis();
        sum(file);
        end = System.currentTimeMillis();
        System.out.println(sum + "共用时" + (end - start) + "毫秒");
    }

    private static int sum = 0;

    private static void sum(File file) {
        int count = 0;
        File[] fileList = file.listFiles();
        if (fileList != null) {
            for (File eachFile : fileList) {
                if (eachFile.isDirectory()) {
                    sum(eachFile);
                } else {
                    sum++;
                }
            }
        }
    }
}

求1到10000000的和

package com.scream.study.thread.ForkJoin.recursivetask;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class SumNumbers extends RecursiveTask<Integer> {
    private Integer start;

    private Integer end;

    private Integer step;

    public SumNumbers(Integer start, Integer end, Integer step) {
        this.start = start;
        this.end = end;
        this.step = step;
    }

    @Override
    protected Integer compute() {
        int result = 0;
        List<SumNumbers> tastList = new ArrayList<>();
        if (end - start <= step) {
            for (int i = start; i <= end; i++) {
                result += i;
            }
        } else {
//            System.out.println("走了else");
            int middle = (start + end) / 2;
            SumNumbers before = new SumNumbers(start, middle, step);
            SumNumbers after = new SumNumbers(middle + 1, end, step);
            tastList.add(before);
            tastList.add(after);
        }
        if (tastList.size() > 0) {
            tastList = (List<SumNumbers>) invokeAll(tastList);
            for (SumNumbers task : tastList) {
//                task.fork();
                result += task.join();
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int time = 10000000;
        Long start = System.currentTimeMillis();
        SumNumbers sumNumber = new SumNumbers(1, time, 1);
        ForkJoinPool poll = new ForkJoinPool();
        poll.invoke(sumNumber);
        System.out.println(sumNumber.join());
        Long end = System.currentTimeMillis();
        System.out.println("共用时" + (end - start) + "毫秒");

        start = System.currentTimeMillis();
        System.out.println(sum(1, time));
        end = System.currentTimeMillis();
        System.out.println("共用时" + (end - start) + "毫秒");
    }

    private static int sum(int begin, int end) {
        int result = 0;
        for (int i = begin; i <= end; i++) {
            result+=i;
        }
        return result;
    }
}

你可能感兴趣的:(在工作中学到的知识,Java的学习之路)