Java 控制线程

1、join

public class JoinThreadTest extends Thread {
    
    public JoinThreadTest(String name){
        super(name);
    }
    
    @Override
    public void run() {
        for(int i = 0; i < 100; i++){
            System.out.println(getName() + " " + i);
        }
    }
    
    public static void main(String[] args) {
        for(int i = 0; i < 1000; i++){
            if (i== 20) {
                JoinThreadTest joinThreadTest = new JoinThreadTest("JoinThread");
                joinThreadTest.start();
                try {
                    joinThreadTest.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }

}

当调用join方法后,主线程将进入阻塞状态,直到被join()方法加入的join线程执行完成为止。通常用来将大问题化为小问题,每个小问题分配一个线程,当这些小问题线程执行完成后,再调用主线程做进一步的处理。

2、后台线程Daemon

主线程默认是前台线程,由前台线程创建的线程默认是前台线程,由后台线程创建的线程默认为后台线程。当所有的前台线程都死亡后,后台线程会自动死亡。设置线程为后台线程,调用setDaemon(true)必须在start()之前调用,判断一个线程是否为后台线程可用isDaemon()判断。

public class DaemonThreadTest extends Thread{
    
    public DaemonThreadTest(String name){
        super(name);
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(getName() + " " + i);
        }
    }
    
    public static void main(String[] args) {
        DaemonThreadTest daemonThreadTest = new DaemonThreadTest("DaemonThread");
        daemonThreadTest.setDaemon(true);
        daemonThreadTest.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

运行如上代码后可知,DaemonThread不会输出到999,而是当主线成执行完后,过了一段时间后,DaemonThread也就结束了。

 3、sleep 和 yield

sleep调用后使线程进入阻塞状态,在该线程的睡眠时间内,即使cpu空闲,线程也不会获得执行机会。睡眠结束后,线程进入就绪状态,等待调度进入运行状态。对所有优先级的线程有效。

yield 只是简单让当前线程暂停一下,使线程调度器重新调度,只对优先级大于等于当前线程的线程有效。当前线程也有可能在暂停一下后,立即调度再次进入运行态。

另外调用sleep会抛出InterruptException,而yield不会。

public class YieldTest extends Thread {
    
    public YieldTest(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + " " + i);
            if (i== 20) {
                Thread.yield();
            }
        }
    }
    
    public static void main(String[] args) {
        YieldTest yieldTest1 = new YieldTest("High");
        yieldTest1.setPriority(MAX_PRIORITY);
        yieldTest1.start();
        
        YieldTest yieldTest2 = new YieldTest("Low");
        yieldTest2.setPriority(MIN_PRIORITY);
        yieldTest2.start();
    }

}

由于如上代码设置了不同优先级,执行如上代码,当执行到i==20时,High线程虽然让出资源,但是优先级高,重新调度后,还是High线程继续执行,注释掉设置优先级的两行代码后执行,可发现在i==20后,线程调度,High线程会出让资源给Low运行。

4、改变线程的优先级

线程优先级设置如上例,子线程的优先级默认与父线程的优先级一致。

你可能感兴趣的:(Java 控制线程)