1.后台线程
/** * * @author emmet1988.iteye.com * * 后台线程的任务是为其他线程提供服务,JVM的垃圾回收线程是典型的后台线程。 * 调用Thread对象的setDaemon方法可将指定线程设置成后台线程,当所有的前台线程 * 死亡时,后台线程也将随之死亡,虚拟机也将自动退出。 * * 注意点: * 1.主线程默认是前台线程 * 2.前台线程创建的子线程默认是前台线程,后台线程创建的子线程默认是后台线程 * 3.将某个线程设置为后台线程必须在该线程start之前 * 4.可以使用isDaemon方法来判断指定线程是否是后台线程 * */ public class DaemonThread extends Thread { @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("后台线程:"+getName()+" "+i); } } public static void main(String[] args) { DaemonThread daemonThread = new DaemonThread(); daemonThread.setDaemon(true); daemonThread.start(); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+" "+i); } // 程序执行到此处,前台线程(main线程)结束,后台线程也将随之结束 } }
2.FirstThread.java
/** * * @author emmet1988.iteye.com * * 注意查看变量i在两个新线程中的值,我们可以知道,使用继承Thread * 类的方法来创建线程类,多条线程之间无法共享线程类的实例变量。 * * 这里有几点需要注意一下: * 1.当主线程结束的时候,其他线程不受任何影响,并不会随之结束。 * 2.测试线程的死亡状态可以用isAlive方法来判断,新建和死亡状态的 * 线程返回false,就绪,运行和阻塞的线程返回true。 * 3.不可以对已经死亡的线程再次调用start方法,start方法只能对新建状态 * 的线程调用,对新建状态下的线程两次调用start方法也是错误的,都会抛出 * IllegalThreadStateException异常。 * */ public class FirstThread extends Thread { private int i; @Override public void run() { // super.run(); for (; i < 10; i++) { System.out.println("子线程: "+getName()+"| i = "+i); } } public static void main(String[] args) { // TODO Auto-generated method stub for (int i = 0; i < 10; i++) { System.out.println("主线程: "+Thread.currentThread().getName()+"| 局部:i = "+i); if(i == 2){ System.out.println("启动2个新线程"); new FirstThread().start(); new FirstThread().start(); } } } }
3.SecondThread.java
/** * * @author emmet1988.iteye.com * * 采用实现Runnable接口的形式创建的多条线程可以共享线程类的实例属性 * 这一点要和通过继承Thread创建的线程区别开来。这是因为使用Runnable * 接口创建的线程,Runnable对象只是作为线程的一个target,而多条线程可 * 以共享同一个target,所以多条线程可以共享同一个target类的实例属性。 * */ public class SecondThread implements Runnable { private int i; @Override public void run() { for (; i < 10; i++) { System.out.println(Thread.currentThread().getName()+" |成员: i = "+i); } } public static void main(String[] args) { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+" | 局部:i = "+i); if (i == 2) { SecondThread secondThread = new SecondThread(); new Thread(secondThread,"新线程1").start(); new Thread(secondThread,"新线程2").start(); } } } }
4.线程休眠sleep
import java.util.Date; /** * * @author emmet1988.iteye.com * * 让线程休眠一段时间,并进入阻塞状态。 */ public class SleepThread extends Thread { public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 5; i++) { System.out.println("当前时间:"+new Date()); sleep(1000); } } }
5.让出当前线程yield
/** * * @author emmet1988.iteye.com * * yield的方法是让当前正在执行的线程暂停,但是它不会阻塞该线程,它只是将该 * 线程转入就绪状态,yield只是让当前线程暂停一下,让系统的线程调度器重新调度 * 一次,完全可能的情况是:当某个线程调用了yield方法暂停之后,线程再次被调度出来 * 重新执行,因为当某个正在执行的线程调用了yield方法暂停之后,只有优先级比当前线程的优先级 * 更高的线程或者与当前线程优先级相同的线程才会获得执行机会。 * * 关于优先级在这里说明一下: * 1.每个线程默认的优先级都与创建该线程的父线程具有相同的优先级 * 2.main方法具有普通优先级,优先级的值为5 * 3.可以通过setPriority(int newPriority)和getPriority()来设置和得到线程的优先级(newPriority的值在1-10之间) * 系统有三个优先级常量:MAX_PRIORITY,MIN_PRIORITY,NORM_PRIORITY,分别是10,1,5 */ public class YieldThread extends Thread { public YieldThread(){ // YieldThread.setDefaultUncaughtExceptionHandler(getDefaultUncaughtExceptionHandler()); YieldThread.setDefaultUncaughtExceptionHandler(ueh); } Thread.UncaughtExceptionHandler ueh = new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { // 处理该线程类所有实例可能抛出的未被捕获的异常 } }; public YieldThread(String name){ super(name); } @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(""+Thread.currentThread().getName()+" "+i); if (i == 2) { // 当i等于2时,使用yield方法来让当前线程让步(让该线程重新进入就绪状态) Thread.yield(); } } } public static void main(String[] args) { // 启动两条并发线程 YieldThread yt1 = new YieldThread("优先级高"); yt1.setPriority(MAX_PRIORITY); yt1.start(); YieldThread yt2 = new YieldThread("优先级低"); yt2.setPriority(MIN_PRIORITY); yt2.start(); } }
6.让一个线程等待另一个线程的完成 join
/** * * @author emmet1988.iteye.com * * Thread提供了让一个线程等待另一个线程执行完成的方法:join方法。 * 当某个线程的执行流中调用了其他线程的join方法时,则调用线程将 * 被阻塞,直到被join方法加入的join线程完成为止。 * * join方法有三种重载的形式: * 1.join(); 等待被join的线程执行完成。 * 2.join(long millis); 等待被join的线程的时间最长为millis毫秒。 * 2.join(long millis,int nanos); 等待被join的线程的最长时间为millis毫秒 加上nanos毫秒(千分之一毫秒)。 */ public class JoinThread extends Thread { public JoinThread(String name){ super(name); } @Override public void run() { // super.run(); for (int i = 0; i < 10; i++) { System.out.println("子线程:"+getName()+" "+i); } } public static void main(String[] args) throws InterruptedException { new JoinThread("新线程").start(); for (int i = 0; i < 10; i++) { if (i==2 ) { JoinThread jt = new JoinThread("被Join的线程"); jt.start(); // 在main线程的执行流中(即本方法)调用了jt线程的Join方法, // 则main线程必须执行结束才会向下继续执行。 jt.join(); } System.out.println("主线程:"+Thread.currentThread().getName()+" "+i); } } }