Java粗淺認識-併發程式設計(三)
阿新 • • 發佈:2018-12-23
執行緒啟動
實現java.lang.Runnable
常用方式
public static class Task implements Runnable {
@Override
public void run() {
System.out.println("執行任務。");
}
}
啟動執行緒
public static void main(String[] args) throws ExecutionException, InterruptedException { //實現Runnable Thread thread = new Thread(new Task()); thread.start(); }
繼承java.lang.Thread
public static class MyThread extends Thread {
@Override
public void run() {
System.out.println("執行任務。");
}
}
啟動執行緒
public static void main(String[] args) throws ExecutionException, InterruptedException { //繼承Thread MyThread myThread = new MyThread(); myThread.start(); }
實現java.util.concurrent.Callable
帶返回值的介面,在java.util.concurrent.ExecutorService內執行。
public static class CallableTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
//計算結果
return 0;
}
}
啟動執行緒
public static void main(String[] args) throws ExecutionException, InterruptedException { //實現Callable,配合執行緒池(executorService介面的submit)使用,具有返回值 CallableTask callableTask = new CallableTask(); ExecutorService executorService = new ThreadPoolExecutor(4, 8, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1 << 4)); Future<Integer> integerFuture = executorService.submit(callableTask); System.out.println(integerFuture.get()); executorService.shutdown(); }
java.util.Timer定時器(java 1.3)
現在不建議使用,建議用java.util.concurrent.ScheduledExecutorService代替。
//Timer,不建議使用了,無法控制,建議是用java.util.concurrent.ScheduledExecutorService代替
Timer timer = new Timer();
//10s後執行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("定時任務");
}
}, 1000 * 10);
java.util.concurrent.ForkJoinPool
在java1.7新增的應該屬於執行緒池範疇,寫在這裡了,fork,join,後面詳細講講它的實現,它執行java.util.concurrent.ForkJoinTask
執行任務分類java.util.concurrent.RecursiveAction不帶返回值的遞迴操作,java.util.concurrent.RecursiveTask帶返回值的遞迴操作。
接下來我們用分別用單執行緒和ForkJoinPoll對陣列排序,求斐波拉契數列第n位數是什麼
單執行緒歸併排序
private static void mergeSort() {
int[] array = randomArray(100, 100);
mergeSort(array, 0, array.length - 1);
printArray(array, "排序結果:");
}
private static void mergeSort(int[] array, int left, int right) {
if (left >= right) {
return;
}
int mid = left + ((right - left) >>> 1);
//左邊排序
mergeSort(array, left, mid);
//右邊排序
mergeSort(array, mid + 1, right);
//左後排序後合併
merge(array, left, mid, right);
}
private static void merge(int[] array, int left, int mid, int right) {
int[] helper = new int[right - left + 1];
int helperIndex = 0;
int l = left;
int r = mid + 1;
while (l <= mid && r <= right) {
helper[helperIndex++] = array[l] < array[r] ? array[l++] : array[r++];
}
while (l <= mid) {
helper[helperIndex++] = array[l++];
}
while (r <= right) {
helper[helperIndex++] = array[r++];
}
System.arraycopy(helper, 0, array, left, helper.length);
}
ForkJoinPool排序
//forkJoin多執行緒排序
forkJoinPool.invoke(new MyRecursiveAction(array, 0, array.length - 1));
printArray(array, "結果:");
/**
* 沒有返回值的遞迴任務,排序
*/
public static class MyRecursiveAction extends RecursiveAction {
int[] array;
int left;
int right;
public MyRecursiveAction(int[] array, int left, int right) {
this.array = array;
this.left = left;
this.right = right;
}
@Override
protected void compute() {
if (left >= right) {
return;
}
int mid = left + ((right - left) >>> 1);
invokeAll(new MyRecursiveAction(array, left, mid), new MyRecursiveAction(array, mid + 1, right));
merge(array, left, mid, right);
}
private void merge(int[] array, int left, int mid, int right) {
int[] helper = new int[right - left + 1];
int helperIndex = 0;
int l = left;
int r = mid + 1;
while (l <= mid && r <= right) {
helper[helperIndex++] = array[l] < array[r] ? array[l++] : array[r++];
}
while (l <= mid) {
helper[helperIndex++] = array[l++];
}
while (r <= right) {
helper[helperIndex++] = array[r++];
}
System.arraycopy(helper, 0, array, left, helper.length);
}
}
單執行緒斐波拉契數列求值
private static int fibonacci(int value) {
if (value == 1 || value == 2) {
return 1;
}
return fibonacci(value - 1) + fibonacci(value - 2);
}
ForkJoinPool斐波拉契數列求值
//forkJoin多執行緒求斐波拉契數列第n個數
ForkJoinTask<Integer> forkJoinTask= forkJoinPool.submit(new MyRecursiveTask(10));
System.out.println("結果"+forkJoinTask.get());
/**
* 帶返回值遞迴任務,累加
*/
public static class MyRecursiveTask extends RecursiveTask<Integer> {
private int value;
public MyRecursiveTask(int value) {
this.value = value;
}
@Override
protected Integer compute() {
if (value == 1 || value == 2) {
return 1;
}
MyRecursiveTask task1 = new MyRecursiveTask(value - 1);
task1.fork();
MyRecursiveTask task2 = new MyRecursiveTask(value - 2);
task2.fork();
return task1.join() + task2.join();
}
}
總結
Java中執行緒啟動就講完了,下一講,程序內執行緒間通訊。
以下是完成程式碼:
/**
* @author baopz
*/
public class UsingThread {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//實現Runnable
Thread thread = new Thread(new Task());
thread.start();
//繼承Thread
MyThread myThread = new MyThread();
myThread.start();
//實現Callable,配合執行緒池(executorService介面的submit)使用,具有返回值
CallableTask callableTask = new CallableTask();
ExecutorService executorService = new ThreadPoolExecutor(4, 8, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1 << 4));
Future<Integer> integerFuture = executorService.submit(callableTask);
System.out.println(integerFuture.get());
executorService.shutdown();
//Timer,不建議使用了,無法控制,建議是用java.util.concurrent.ScheduledExecutorService代替
Timer timer = new Timer();
//10s後執行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("定時任務");
}
}, 1000 * 10);
//1.7,先分開,後合併,歸併
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
int[] array = randomArray(100, 100);
//單執行緒歸併排序
mergeSort();
//forkJoin多執行緒排序
forkJoinPool.invoke(new MyRecursiveAction(array, 0, array.length - 1));
printArray(array, "結果:");
//單執行緒斐波拉契數列,第n個數是什麼?1、1、2、3、5、8、13、21、34、55
System.out.println(fibonacci(10));
//forkJoin多執行緒求斐波拉契數列第n個數
ForkJoinTask<Integer> forkJoinTask= forkJoinPool.submit(new MyRecursiveTask(10));
System.out.println("結果"+forkJoinTask.get());
}
private static int fibonacci(int value) {
if (value == 1 || value == 2) {
return 1;
}
return fibonacci(value - 1) + fibonacci(value - 2);
}
private static int[] randomArray(int size, int bound) {
int[] array = new int[100];
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt(1000);
}
printArray(array, "隨機陣列:");
return array;
}
private static void printArray(int[] array, String prefix) {
if (prefix != null) {
System.out.println(prefix);
}
for (int i : array) {
System.out.print(i + " ");
}
System.out.println();
}
private static void mergeSort() {
int[] array = randomArray(100, 100);
mergeSort(array, 0, array.length - 1);
printArray(array, "排序結果:");
}
private static void mergeSort(int[] array, int left, int right) {
if (left >= right) {
return;
}
int mid = left + ((right - left) >>> 1);
//左邊排序
mergeSort(array, left, mid);
//右邊排序
mergeSort(array, mid + 1, right);
//左後排序後合併
merge(array, left, mid, right);
}
private static void merge(int[] array, int left, int mid, int right) {
int[] helper = new int[right - left + 1];
int helperIndex = 0;
int l = left;
int r = mid + 1;
while (l <= mid && r <= right) {
helper[helperIndex++] = array[l] < array[r] ? array[l++] : array[r++];
}
while (l <= mid) {
helper[helperIndex++] = array[l++];
}
while (r <= right) {
helper[helperIndex++] = array[r++];
}
System.arraycopy(helper, 0, array, left, helper.length);
}
/**
* 帶返回值遞迴任務,累加
*/
public static class MyRecursiveTask extends RecursiveTask<Integer> {
private int value;
public MyRecursiveTask(int value) {
this.value = value;
}
@Override
protected Integer compute() {
if (value == 1 || value == 2) {
return 1;
}
MyRecursiveTask task1 = new MyRecursiveTask(value - 1);
task1.fork();
MyRecursiveTask task2 = new MyRecursiveTask(value - 2);
task2.fork();
return task1.join() + task2.join();
}
}
/**
* 沒有返回值的遞迴任務,排序
*/
public static class MyRecursiveAction extends RecursiveAction {
int[] array;
int left;
int right;
public MyRecursiveAction(int[] array, int left, int right) {
this.array = array;
this.left = left;
this.right = right;
}
@Override
protected void compute() {
if (left >= right) {
return;
}
int mid = left + ((right - left) >>> 1);
invokeAll(new MyRecursiveAction(array, left, mid), new MyRecursiveAction(array, mid + 1, right));
merge(array, left, mid, right);
}
private void merge(int[] array, int left, int mid, int right) {
int[] helper = new int[right - left + 1];
int helperIndex = 0;
int l = left;
int r = mid + 1;
while (l <= mid && r <= right) {
helper[helperIndex++] = array[l] < array[r] ? array[l++] : array[r++];
}
while (l <= mid) {
helper[helperIndex++] = array[l++];
}
while (r <= right) {
helper[helperIndex++] = array[r++];
}
System.arraycopy(helper, 0, array, left, helper.length);
}
}
public static class CallableTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return 0;
}
}
public static class MyThread extends Thread {
@Override
public void run() {
System.out.println("執行任務。");
}
}
public static class Task implements Runnable {
@Override
public void run() {
System.out.println("執行任務。");
}
}
}