线程(二)——线程的状态及常用方法

来源:互联网 发布:菜鸟网络上市 编辑:程序博客网 时间:2024/06/06 02:26

一.线程的状态


 1.新建状态(New):
  当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
 2.就绪状态(Runnable):
  当调用线程对象的start()方法,线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
  另外,start()方法是让线程进入就绪状态,而run()方法只是一个普通方法,当线程进入运行状态的时候会执行线程的run()方法。

public class TestRunAndStart {    public static void main(String[] args) {        new Thread("线程一") {            @Override            public void run() {                super.run();                System.out.println("当前运行的线程为:"Thread.currentThread().getName());            }        }.start();        new Thread("线程二") {            @Override            public void run() {                super.run();                System.out.println("当前运行的线程为:"Thread.currentThread().getName());            }        }.run();    }}

  运行结果:

当前运行的线程为:线程一当前运行的线程为:main

 3.运行状态(Running):
  当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。
  注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
 4.阻塞状态(Blocked):
  处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
  (1).等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
  (2).同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
  (3).其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
 5.死亡状态(Dead):
  线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

二.线程类的常用方法

 1.构造方法

方法 作用 Thread() 创建新的线程对象,该线程默认名称为自动生成,形式为 “Thread-“+n ,其中的 n 为整数。
该方法通常用于创建匿名内部类并重写 run() 方法。 Thread(Runnable target) 创建新的线程对象, target 对象为该新线程对象 run() 方法被调用的对象。 Thread(String name) 创建新的线程对象, name 为该线程的名称。 Thread(ThreadGroup group,Runnable target) 创建新的线程对象, group 为该线程所属的线程组。target 对象为该新线程对象 run() 方法被调用的对象。 Thread(ThreadGroup group,Runnable target,String name,long stackSize) 创建新的线程对象,group 为该线程所属的线程组, target 对象为该新线程对象 run() 方法被调用的对象, name 为该线程的名称, stackSize 新线程的预期堆栈大小,为零时表示忽略该参数。
stackSize 参数(如果有)的作用具有高度的平台依赖性,在某些平台上, stackSize 参数的值无论如何不会起任何作用。通常建议,可以让虚拟机自由处理 stackSize 参数。

(1).Thread()

public void emptyConstitution(){    new Thread(){        @Override        public void run() {            System.out.println("新线程执行");        }    }.start();}

  控制台输出

新线程执行

(2).Thread(Runnable target)

public void runnableConstitution(){    new Thread(new Runnable() {        public void run() {            System.out.println("新的runnable方法");        }    }).start();}

  控制台输出

新的runnable方法

(3).Thread(String name)

public void nameConstitution(){    new Thread("MyThread"){        @Override        public void run() {            System.out.println("新的线程名为:"+this.getName());        }    }.start();}

  控制台输出

新的线程名为:MyThread

 2.静态方法

方法 返回值类型 作用 currentThread() Thread 返回对当前正在执行的线程对象的引用。 holdsLock(Object obj) boolean 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true 。 sleep(long millis) void 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 sleep(long millis, int nanos) void 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 yield() void 暂停当前正在执行的线程对象,并执行其他线程。 setDefaultUncaughtExceptionHandler
(UncaughtExceptionHandler eh) void 设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序。

(1).holdsLock(Object obj)

@Testpublic void static_HoldsLock() {    Object lock = new Object();    synchronized (lock) {        System.out.println("synchronized代码块中:" + Thread.holdsLock(lock));    }    System.out.println("synchronized代码块外:" + Thread.holdsLock(lock));}

  控制台输出

synchronized代码块中:truesynchronized代码块外:false

(2).sleep(Object obj)

@Testpublic void static_sleep() throws InterruptedException {    long start = System.currentTimeMillis();    Thread.sleep(1000);    long end = System.currentTimeMillis();    System.out.println("线程休眠了" + (end - start) + "毫秒");}

  控制台输出

线程休眠了1001毫秒

(3).yield()

//该变量为共享变量,volatile关键字保证了线程间的可见性private volatile boolean static_Yield_Flag = false;@Testpublic void static_Yield() {    new Thread("新线程") {        @Override        public void run() {            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }            static_Yield_Flag = true;            System.out.println("isContinue状态修改为:ture");            System.out.println(Thread.currentThread().getName() + "结束");        }    }.start();    while (!static_Yield_Flag) {        Thread.yield();    }    System.out.println("主线程结束");}

  控制台输出

isContinue状态修改为:ture新线程结束主线程结束

(4).setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)

@Testpublic void static_SetDefaultUncaughtExceptionHandler() {    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {        public void uncaughtException(Thread t, Throwable e) {           System.out.println(t.getName()+"线程使用了全局异常处理器,异常信息:" + e.getMessage());        }    });    new Thread("新线程") {        @Override        public void run() {            System.out.println(1 / 0);//可以调用全局UncaughtExceptionHandler        }    }.start();    System.out.println("抛异常前");    //没有局部UncaughtExceptionHandler,返回当前ThreadGroup    System.out.println(Thread.currentThread().getUncaughtExceptionHandler());    throw new RuntimeException("抛异常");}

  控制台输出

抛异常前java.lang.ThreadGroup[name=main,maxpri=10]全局:/ by zerojava.lang.RuntimeException: 抛异常    at com.xin.thread.demo04_threadMethod._Main_ThreadMethodTest.static_SetDefaultUncaughtExceptionHandler(_Main_ThreadMethodTest.java:80)    ......

  在JUnit测试时主线程抛的异常不会走全局的UncaughtExceptionHandler(未知原因),而新创建的线程则会走全局UncaughtExceptionHandler。
  然而在main方法调用时主线程抛的异常不能走UncaughtExceptionHandler,估计应该与JUnit内部实现有关(未看过JUnit源码不好下定论)。

 3.实例方法

方法 返回值类型 作用 getId() long 返回该线程的标识符。 getName() String 返回该线程的名称。 setName(String name) void 改变线程名称,使之与参数 name 相同。 getPriority() int 返回线程的优先级。 setPriority(int newPriority) void 更改线程的优先级。参数newPriority应大于等于1,小于等于10,否则会抛出IllegalArgumentException getState() Thread.State 返回该线程的状态。 该方法用于监视系统状态,不用于同步控制。 getThreadGroup() ThreadGroup 返回该线程所属的线程组。 isAlive() boolean 测试线程是否处于活动状态。 isDaemon() boolean 测试该线程是否为守护线程。 setDaemon(boolean on) void 将该线程标记为守护线程或用户线程。

(1).getState()

@Testpublic void getState() throws InterruptedException {    Thread t = new Thread("新线程") {        @Override        public void run() {            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(getName() + "完成");        }    };    System.out.println("创建后状态为:" + t.getState());    t.start();    System.out.println("调用start()方法后状态为:" + t.getState());    Thread.sleep(50);    System.out.println("调用sleep()方法后状态为:" + t.getState());    Thread.sleep(150);    if (!t.isAlive()) {        System.out.println("线程方法后状态为:" + t.getState());    }}

  控制台输出

创建后状态为:NEW调用start()方法后状态为:RUNNABLE调用sleep()方法后状态为:TIMED_WAITING新线程完成线程方法后状态为:TERMINATED

(2).isAlive()

@Testpublic void isAlive() throws InterruptedException {    Thread t = new Thread("新线程") {        @Override        public void run() {            System.out.println(getName() + "结束");        }    };    System.out.println(t.isAlive());    t.start();    System.out.println(t.isAlive());    Thread.sleep(100);    System.out.println(t.isAlive());}

  控制台输出

falsetrue新线程结束false

(3).setDaemon()

@Testpublic void setDaemon() throws InterruptedException {    Thread t = new Thread("新线程") {        @Override        public void run() {            while (true) {                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(getName() + "运行中");            }        }    };    t.setDaemon(true);    t.start();    System.out.println(t.getName() + "为守护线程:" + t.isDaemon());    Thread.sleep(500);}

  控制台输出

新线程为守护线程:true新线程运行中新线程运行中新线程运行中新线程运行中

  守护线程又叫后台线程,最常见的守护线程就是垃圾回收线程。当程序中所有正在运行中的线程都是守护线程时,程序就会退出(守护线程也会结束运行);而只要有一条还在运行的线程为用户线程(即非守护线程),则守护线程将会继续运行。

阅读全文
0 0