JAVA线程控制

来源:互联网 发布:上海美团数据分析 编辑:程序博客网 时间:2024/06/07 15:31

Join

    分治思想的线程应用。    join()方法可以一个让线程等待另一个线程执行完成: 调用线程被阻塞,直到被join()的线程执行完成. 该方法通常由主线程调用,将大问题划分成小问题,每个小问题分配一个线程执行,当所有的小问题处理完成,再由主线程来做最后处理.如多线程排序,将一个大的排序任务分割为几个小块,分配给几个线程,当所有子线程执行完成后,再由主线程进行归并:
public class MultiThreadSortWithJoin {    private static final int THREAD_COUNT = 12; /*12个线程分段排序*/    private static final int NUMBER_COUNT = 201600;    private static final int PER_COUNT = NUMBER_COUNT / THREAD_COUNT;    private static final int RANDOM_LIMIT = 10000000;    public static void main(String[] args) throws InterruptedException {        // 为数组分配随机值, 为了方便查看, 为其分配10000000以内的值        Random random = new Random();        int[] array = new int[NUMBER_COUNT];        for (int i = 0; i < NUMBER_COUNT; ++i) {            array[i] = random.nextInt(RANDOM_LIMIT);        }        List<Thread> threadList = new LinkedList<Thread>();        for (int index = 0; index < THREAD_COUNT; ++index) {            Thread t = new Thread(new SortThread(array, index * PER_COUNT, (index + 1) * PER_COUNT));            t.start();            threadList.add(t);            System.out.println(t.getPriority());        }        // 等待线程排序完成        join(threadList);        // 分段合并        int[] result = merge(array, PER_COUNT, THREAD_COUNT);        if (check(result)) {            System.out.println("correct");        }    }    private static boolean check(int[] array) {        for (int i = 0; i < array.length - 1; ++i) {            if (array[i] > array[i + 1]) {                System.out.println("error");                return false;            }        }        return true;    }    private static void join(List<Thread> threads) throws InterruptedException {        for (Thread thread : threads) {            System.out.println("Call join method !");            thread.join();        }    }    /**     * 分段合并     *     * @param array 已经分段排好序的数组     * @param size  每段的长度     * @param count 一共的段数     * @return     */    private static int[] merge(int[] array, int size, int count) {        // indexes保存array每段的起始位置        int[] indexes = new int[count];        for (int i = 0; i < count; ++i) {            indexes[i] = i * size;        }        int[] result = new int[array.length];        // i保存result下标        for (int i = 0; i < result.length; ++i) {            int minNumber = Integer.MAX_VALUE;            int minIndex = 0;            // 内层for循环的作用: 找出这count段中最小的那个值            for (int index = 0; index < indexes.length; ++index) {                // indexes[index]: 当前段的起始位置                if ((indexes[index] < (index + 1) * size) && (array[indexes[index]] < minNumber)) {                    minNumber = array[indexes[index]];                    minIndex = index;                }            }            result[i] = minNumber;            indexes[minIndex]++;        }        return result;    }    private static class SortThread implements Runnable {        private int[] array;        private int start;        private int end;        public SortThread(int[] array, int start, int end) {            this.array = array;            this.start = start;            this.end = end;        }        public void run() {            // 分段排序            Arrays.sort(array, start, end);        }    }}

后台线程

   后台线程的任务是为其他线程提供服务,又被成为”守护线程”, JVM的垃圾回收线程就是典型的后台守护线程. 调用Thread对象的setDaemon(true)方法可以将指定线程设置成后台线程(在start()之前),isDaemon()可以判断是否为后台线程(主线程默认是非后台线程, 非后台线程创建的默认是非后台线程, 反之亦然).   后台线程的特征: 所有前台线程死亡, 后台线程会自动死亡.

Sleep

前面多次看到在线程的执行过程中调用sleep()让线程睡眠(进入阻塞状态),以模拟耗时的操作. 其方法签名如下:
static void sleep(long millis) throws InterruptedException;

Yield

   yield()方法让当前正在执行的线程暂停,但不是阻塞线程,而是让该线程转入就绪状态,重新等待调度.实际上,当某个线程调用yield()方法让出处理器资源后,只有优先级与当前线程相同,或优先级比当前线程更高的处于就绪的线程才会获得执行机会, 因此完全有可能线程转入就绪后,调度器又将其调度出来重新执行.  **注意:** yield()方法可移植性并不是很好, 而且很有可能导致死锁.所以并不推荐使用(详细见线程同步).

线程优先级

每个线程都具有一定的优先级,优先级高的线程获得更多的执行机会;默认情况下,每个子线程的优先级与子父线程相同(默认main线程具有普通优先级).Thread类提供了setPriority(int newPriority)/getPriority()方法来设置/获取线程优先级.newPriority的范围为1~10,但由于这些级别需要操作系统的支持,但不同操作系统的优先级策略并不相同,因此推荐使用Thread类提供了三个静态常量进行设置:
/** * The minimum priority that a thread can have. */public final static int MIN_PRIORITY = 1;/** * The default priority that is assigned to a thread. */public final static int NORM_PRIORITY = 5;/** * The maximum priority that a thread can have. */public final static int MAX_PRIORITY = 10;
public class ThreadPriority {    public static void main(String[] args) {        Thread low = new Thread(new PriorityRunnable(), "low");        low.setPriority(Thread.MIN_PRIORITY);        Thread mid = new Thread(new PriorityRunnable(), "mid");        mid.setPriority(Thread.NORM_PRIORITY);        Thread high = new Thread(new PriorityRunnable(), "high");        high.setPriority(Thread.MAX_PRIORITY);        start(low, mid, high);    }    private static void start(Thread... threads) {        for (Thread thread : threads) {            thread.start();        }    }    private static class PriorityRunnable implements Runnable {        public void run() {            for (int i = 0; i < 10; ++i) {                System.out.println(Thread.currentThread().getName() + " " + i);            }        }    }}
0 0
原创粉丝点击