多线程基础四(三)、yield方法、线程优先级以及守护线程

来源:互联网 发布:java使用openoffice 编辑:程序博客网 时间:2024/05/16 06:15

1. yield() 方法

使线程放弃当前的CPU资源(多个线程争抢CPU资源去执行,包括刚放弃的此线程)。但放弃的时间不确定,也有可能刚刚放弃,马上又抢到CPU资源运行。

public class MyThread extends Thread {    @Override    public void run() {        long beginTime = System.currentTimeMillis();        int count = 0;        for (int i = 0; i < 50000000; i++) {            Thread.yield();            count = count + (i + 1);        }        long endTime = System.currentTimeMillis();        System.out.println("用时:" + (endTime - beginTime) + "毫秒!");    }}
public class Test {    public static void main(String[] args) {        MyThread thread = new MyThread();        thread.start();    }    /*    运行结果:    (无yield)    用时:8毫秒!    (有yield)    用时:3166毫秒!     */}
将CPU资源让出导致运行时间变长

2. 线程优先级

在操作系统中,线程可以划分优先级,优先级较高的线程得到的CPU资源较多,也就是 CPU优先执行优先级较高的线程对象中的任务

(1)设置线程的优先级使用 setPriority() 方法,源码如下:

public final void setPriority(int newPriority) {        ThreadGroup g;        checkAccess();        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {            throw new IllegalArgumentException();        }        if((g = getThreadGroup()) != null) {            if (newPriority > g.getMaxPriority()) {                newPriority = g.getMaxPriority();            }            setPriority0(priority = newPriority);        }    }
线程优先级分为1 ~10 这10个等级,超出范围则会抛出 IllegalArgumentException。JDK中使用3个常量来预置定义优先级的值:

public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

(2)线程优先级具有继承特性

在Java中,线程优先级具有继承性,比如 A线程启动B线程,则B线程的优先级与A是一样的

public class MyThread3 extends Thread {    @Override    public void run() {        System.out.println("MyThread3 run priority = " + this.getPriority());    }}
public class MyThread2 extends Thread {    @Override    public void run() {        System.out.println("MyThread2 run priority = " + this.getPriority());        MyThread3 thread3 = new MyThread3();        thread3.start();    }}
public class Test2 {    public static void main(String[] args) {        System.out.println("main thread begin priority = " + Thread.currentThread().getPriority());        //Thread.currentThread().setPriority(6);        System.out.println("main thread end priority = " + Thread.currentThread().getPriority());        MyThread2 thread2 = new MyThread2();        thread2.start();    }    /*    运行结果:    (无 setPriority(6))    main thread begin priority = 5    main thread end priority = 5    MyThread2 run priority = 5    MyThread3 run priority = 5    (有 setPriority(6))    main thread begin priority = 5    main thread end priority = 6    MyThread2 run priority = 6    MyThread3 run priority = 6     */}
(3)优先级具有规则性

public class MyThread4 extends Thread {    @Override    public void run() {        long beginTime = System.currentTimeMillis();        long addResult = 0;        for (int i = 0; i < 10; i++) {            for (int j = 0; j < 50000; j++) {                Random random = new Random();                random.nextInt();                addResult += i;            }        }        long endTime = System.currentTimeMillis();        System.out.println("****** thread4 use time = " + (endTime - beginTime));    }}
public class MyThread5 extends Thread {    @Override    public void run() {        long beginTime = System.currentTimeMillis();        long addResult = 0;        for (int i = 0; i < 10; i++) {            for (int j = 0; j < 50000; j++) {                Random random = new Random();                random.nextInt();                addResult += i;            }        }        long endTime = System.currentTimeMillis();        System.out.println("##### thread5 use time = " + (endTime - beginTime));    }}
public class Test4 {    public static void main(String[] args) {        for (int i = 0; i < 5; i++) {            MyThread4 thread4 = new MyThread4();            thread4.setPriority(10);;            thread4.start();            MyThread5 thread5 = new MyThread5();            thread5.setPriority(1);;            thread5.start();        }    }    /*    运行结果:    ****** thread4 use time = 194    ****** thread4 use time = 238    ****** thread4 use time = 238    ****** thread4 use time = 313    ****** thread4 use time = 325    ##### thread5 use time = 339    ##### thread5 use time = 370    ##### thread5 use time = 371    ##### thread5 use time = 389    ##### thread5 use time = 391    ----------------------------    ****** thread4 use time = 122    ****** thread4 use time = 161    ****** thread4 use time = 166    ##### thread5 use time = 161    ##### thread5 use time = 236    ##### thread5 use time = 286    ****** thread4 use time = 226    ****** thread4 use time = 260    ##### thread5 use time = 256    ##### thread5 use time = 228    ------------------------------    ****** thread4 use time = 130    ****** thread4 use time = 149    ##### thread5 use time = 151    ****** thread4 use time = 100    ****** thread4 use time = 192    ****** thread4 use time = 166    ##### thread5 use time = 204    ##### thread5 use time = 202    ##### thread5 use time = 231    ##### thread5 use time = 332     */}
从结果中,高优先级的线程总是大部分先执行完,但不代表高优先级的线程全部先执行完。下面我们交换 thread4 和 thread5 的优先级,再试一下

public class Test4 {    public static void main(String[] args) {        for (int i = 0; i < 5; i++) {            MyThread4 thread4 = new MyThread4();            thread4.setPriority(1);;            thread4.start();            MyThread5 thread5 = new MyThread5();            thread5.setPriority(10);;            thread5.start();        }    }    /*    运行结果:    ##### thread5 use time = 194    ##### thread5 use time = 255    ##### thread5 use time = 317    ****** thread4 use time = 324    ##### thread5 use time = 345    ****** thread4 use time = 359    ****** thread4 use time = 369    ##### thread5 use time = 373    ****** thread4 use time = 394    ****** thread4 use time = 394    ----------------------------    ****** thread4 use time = 158    ##### thread5 use time = 191    ##### thread5 use time = 202    ##### thread5 use time = 292    ##### thread5 use time = 321    ****** thread4 use time = 307    ##### thread5 use time = 269    ****** thread4 use time = 356    ****** thread4 use time = 236    ****** thread4 use time = 214    ------------------------------    ##### thread5 use time = 170    ##### thread5 use time = 181    ****** thread4 use time = 215    ****** thread4 use time = 228    ##### thread5 use time = 337    ##### thread5 use time = 348    ##### thread5 use time = 353    ****** thread4 use time = 355    ****** thread4 use time = 396    ****** thread4 use time = 393     */}
可以发现,大部分 thread5 先执行完,说明 线程的优先级与代码执行顺序无关,线程的优先级具有一定的规则性,也就是 CPU 会优先将执行资源给优先级比较高的线程
(4)优先级具有随机性

上面代码说明:线程优先级较高则会被优先执行完 run() 方法中的任务,但是并不绝对。线程的优先级还具有“随机性”,优先级较高的线程不一定每次都能先执行完

public class MyThread6 extends Thread {    @Override    public void run() {        long beginTime = System.currentTimeMillis();        for (int i = 0; i < 10; i++) {            for (int j = 0; j < 1000; j++) {                Random random = new Random();                random.nextInt();            }        }        long endTime = System.currentTimeMillis();        System.out.println("****** thread6 use time = " + (endTime - beginTime));    }}
public class MyThread7 extends Thread {    @Override    public void run() {        long beginTime = System.currentTimeMillis();        for (int i = 0; i < 10; i++) {            for (int j = 0; j < 1000; j++) {                Random random = new Random();                random.nextInt();            }        }        long endTime = System.currentTimeMillis();        System.out.println("##### thread7 use time = " + (endTime - beginTime));    }}
public class Test6 {    public static void main(String[] args) {        for (int i = 0; i < 5; i++) {            MyThread6 thread6 = new MyThread6();            thread6.setPriority(5);;            thread6.start();            MyThread7 thread7 = new MyThread7();            thread7.setPriority(6);;            thread7.start();        }    }    /*    运行结果:    ****** thread6 use time = 2    ##### thread7 use time = 2    ****** thread6 use time = 7    ##### thread7 use time = 6    ##### thread7 use time = 1    ##### thread7 use time = 2    ##### thread7 use time = 1    ****** thread6 use time = 14    ****** thread6 use time = 1    ****** thread6 use time = 1    ----------------------------    ****** thread6 use time = 0    ****** thread6 use time = 3    ##### thread7 use time = 12    ##### thread7 use time = 7    ##### thread7 use time = 10    ****** thread6 use time = 1    ****** thread6 use time = 18    ****** thread6 use time = 1    ##### thread7 use time = 2    ##### thread7 use time = 1    ------------------------------    ##### thread7 use time = 7    ****** thread6 use time = 1    ****** thread6 use time = 2    ##### thread7 use time = 10    ##### thread7 use time = 10    ****** thread6 use time = 5    ##### thread7 use time = 6    ****** thread6 use time = 11    ##### thread7 use time = 7    ****** thread6 use time = 13     */}
为了结果体现“随机性”,所以两个线程的优先级一个设置为5,另一个设置为6。从这次的结果来看,并没有明显的规律,所以:不要把线程的优先级与运行结果的顺序作

为衡量的标准,优先级较高的线程不一定每一次都先执行完 run() 方法中的任务

3. 守护线程
Java中有两种线程,一种是用户线程,另一种就是守护(Daemon)线程。

什么是守护线程?守护线程是一种特殊的线程,他的特性有陪伴的含义,当进程中不存在非守护线程了,则守护线程自动销毁。守护线程的作用是为其他线程的运行提供便利服务,最典型的应用就是 GC(垃圾回收器)

public class MyThread extends Thread {    private int i = 0;    @Override    public void run() {        try {            while (true) {                i++;                System.out.println("i = " + i);                Thread.sleep(1000);            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
public class Test {    public static void main(String[] args) {        try {            MyThread thread = new MyThread();            thread.setDaemon(true); //将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。            thread.start();            Thread.sleep(5000);            System.out.println("我离开 thread 对象也不再打印了,也就是停止了");        } catch (InterruptedException e) {            e.printStackTrace();        }    }    /*    运行结果:    i = 1    i = 2    i = 3    i = 4    i = 5    i = 6    我离开 thread 对象也不再打印了,也就是停止了     */}








阅读全文
0 0
原创粉丝点击