实现多线程的三种方法
- 继承Thread,并重写run方法,通过
Thread1 thread1 = new Thread1("first thread");
来使用 - 实现Runnable,并实现run方法,通过
Thread thread = new Thread(new MyThread());
来使用(MyThread实现了Runnable接口 - 实现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;
}
}