你的位置:首页 > Java教程

[Java教程]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、改变线程的优先级

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