join线程:
public class JoinThread extends Thread{ public JoinThread(String name) { super(name); } public void run() { for(int i = 0 ; i < 100 ; i++) { System.out.println(getName() + " " + i); } } public static void main(String[] args) throws InterruptedException { new JoinThread("Thread-0:").start(); for(int i = 0 ; i < 100 ; i++) { if(i == 20) { JoinThread jt = new JoinThread("Join-Thread:"); jt.start(); jt.join(); } System.out.println(Thread.currentThread().getName() + " " + i); } } }
程序中有三个线程,Thread-0开始和main线程并发执行,当主程序i==20时,启动了名为Join-Thread线程,Join-Thread线程执行后和Thread-0并发执行 ,该线程不会和main线程并发执行,mian线程需要等待Join-Thread线程执行完毕之后再开始向下执行。
当某个程序流中调用其他线程的join方法时,那么调用线程将会被阻塞,直到join方法加入的线程执行完成。
join方法的重载:
join(): 等待被join的线程执行完成
join(long millions): 等待被join的线程执行millions毫秒,如果再millios毫秒内还没执行完,就不再等待了
join(long millions , int nanos) 等待被join线程最长millions加nanos毫微妙
后台线程:(守护线程 , 精灵线程)
特征:所有的前台线程都死亡,后台线程会自动死亡。
调用setDaemon(true) 将指定线程设置成为后台线程,需要在start()之前调用,否则引发IllegalThreadStateExcepiton异常
public class DaemonThread extends Thread { public void run() { for(int i = 0 ; i < 1000 ; i++) { System.out.println(getName() + " " + i); } } public static void main(String[] args) { DaemonThread dt = new DaemonThread(); dt.setDaemon(true);//设置成为后台线程 dt.start(); for(int i = 0 ; i < 10 ; i ++) { System.out.println(Thread.currentThread().getName() + " " + i); } //-- main 线程结束后 , 后台线程也随之结束 } }
结果:后台线程可能在main线程结束的时候 并发执行一点,就结束了。
线程睡眠:sleep
如果需要让正在执行的线程暂停一段时间,可以通过Thread类的静态方法sleep()方法来实现
static void sleep(long millis): 让当前正在执行的线程暂停millis毫秒 , 并且进入阻塞状态
static void sleep(long millis , int nanos) 让当前正在执行的线程暂停millis毫秒 加nanos微妙 , 并且进入阻塞状态
public class Thread5 extends Thread{ public void run() { for(int i = 0 ; i < 30 ; i++) { System.out.println(getName() + " " + i); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Thread5 t = new Thread5(); Thread5 t2 = new Thread5(); t.start(); t2.start(); } }
线程让步:yield
yield()和sleep()方法相似,可以让当前正在执行的线程暂停,但是不会阻塞该线程,它是让该线程转入就绪状态。
public class YieldThread extends Thread{ public YieldThread(String name) { super(name); } public void run() { for(int i = 0 ; i < 50 ; i++) { System.out.println(getName() + " 优先级:" + getPriority() + "变量:" + i); if(i == 20) { // Thread.yield(); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { YieldThread y1 = new YieldThread("thread-0"); YieldThread y2 = new YieldThread("xxxxxx"); y1.start(); y2.start(); y1.setPriority(MAX_PRIORITY); y2.setPriority(MIN_PRIORITY); } }
被yield方法暂停后,线程执行会受到优先级影响。
改变线程优先级:
每个线程执行时具有一定的优先级,优先级高的线程获得较多的执行机会,优先级较低的线程获得较少的机会。
每个线程默认的优先级与创建它的父线程的优先级相同,默认情况下,main具有普通优先级,main创建的子线程也具有普通优先级
Thread类提供setPriority(int newPriority) ,getPriority()方法来设置和返回指定线程的优先级 newPriority的值是整数,1-10之间,也可以使用静态常量
MAX_PRIORITY: 10 MIN_PRIORITY:1 NORM_PRIORITY:5
public class PriorityThread extends Thread{ public PriorityThread(String name) { super(name); } public void run() { for(int i = 0 ; i < 50 ; i++) { System.out.println(getName() + " " + "优先级:" + getPriority() + "变量: " + i); } } public static void main(String[] args) { Thread.currentThread().setPriority(6); for(int i = 0; i < 30 ; i++) { if(i == 10) { PriorityThread p1 = new PriorityThread("低级"); p1.start(); p1.setPriority(MIN_PRIORITY); } if(i == 20) { PriorityThread p2 = new PriorityThread("高级"); p2.start(); p2.setPriority(MAX_PRIORITY); } } } }