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、改变线程的优先级
线程优先级设置如上例,子线程的优先级默认与父线程的优先级一致。