thebigdipperbdx的博客

April Showers Bring May Flowers.

Thread常用方法解析

常用方法

java.lang.Thread

  • public static native Thread currentThread(); 返回对当前正在执行的线程对象的引用。
  • public long getId()返回该线程的标识符。
  • public final String getName()返回该线程的名称。
  • public final int getPriority()返回线程的优先级。
  • public void interrupt() 中断线程。
  • public final native boolean isAlive();测试线程是否处于活动状态。
  • public final void join() throws InterruptedException等待该线程终止。
  • public final synchronized void join(long millis) throws InterruptedException等待该线程终止的时间最长为 millis 毫秒。
  • public final synchronized void join(long millis, int nanos) throws InterruptedException 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
  • public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。
  • public final void setPriority(int newPriority) 更改线程的优先级。
  • public static native void sleep(long millis) throws InterruptedException;在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
  • public static void sleep(long millis, int nanos)throws InterruptedException 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
  • public synchronized void start()使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
  • public static native void yield();暂停当前正在执行的线程对象,并执行其他线程。

join

让父线程等待子线程结束之后才能继续运行。

当我们调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行。

举例,在 Parent 调用 child.join() 后,child 子线程正常运行,Parent 父线程会等待 child 子线程结束后再继续运行。

当某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的join线程执行完为止。

public class Test {
    public static void main(String[] args) {
        Thread thread = new MyRunner3();
        thread.start();
        try {
            //主线程等待thread的业务处理完了之后再向下运行  
            //thread和主线程合并了  
            thread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block  
            e.printStackTrace();
        }
        for(int i = 0; i < 100; i++){
            System.out.println("main : " + i);
        }
    }
}
class MyRunner3 extends Thread {
    @Override
    public void run() {
        for(int i = 0; i < 5; i++){
            System.out.println("i am " + getName());
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
} 

sleep-线程睡眠

如果需要让当前正在执行的线程暂停一段时间,并进入阻塞状态,则可以通过调用Thread类的静态sleep()方法来实现。

当当前线程调用sleep()方法进入阻塞状态后,在其睡眠时间内,该线程不会获得执行机会,即使系统中没有其他可执行线程,处于sleep()中的线程也不会执行,因此sleep()方法常用来暂停程序的执行

yield-线程让步

yield()方法和sleep()方法有点相似,它也是Thread类提供的一个静态方法,它也可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转入到就绪状态。即让当前线程暂停一下,让系统的线程调度器重新调度一次,完全可能的情况是:当某个线程调用了yield()方法暂停之后,线程调度器又将其调度出来重新执行。

实际上,当某个线程调用了yield()方法之后,只有优先级与当前线程相同或者比当前线程更高的处于就绪状态的线程才会获得执行机会。

sleep()与yield()方法区别:

1、sleep()方法暂停当前线程后,会给其他线程执行机会,不会理会其他线程的优先级;但yield()方法只会给优先级高或者相同的线程机会

2、sleep()方法会将线程转入到阻塞状态,知道经过阻塞时间才会转入就绪状态;而yield()不会将线程转入阻塞状态,它只是强制当前线程进入就绪状态。因此完全有可能某个线程调用了yield()方法暂停之后,立即再次获取处理器资源被执行。

3、sleep()方法声明抛出InterruptedException异常,所以调用sleep()方法时要么捕捉该异常,要么显示声明抛出该异常;而yield()方法则没有声明抛出任何异常。

4、sleep()方法比yield()方法更好的可移植性,通常不建议使用yield()方法来控制并发线程执行。

isAlive

Tests if this thread is alive. A thread is alive if it has been started and has not yet died.

public class Test {
    public static void main(String args[]) throws IllegalThreadStateException {
        MyThread m = new MyThread();  //实例化Runnable子类对象
        Thread t = new Thread(m, "自定义线程");
        System.out.println("线程执行前:" + t.isAlive());       //false
        t.start();
        //isAlive(),判断线程是否处于活动状态
        System.out.println("线程启动之后:" + t.isAlive());  //true
    }
}

class MyThread implements Runnable  //实现Runnable接口
{
    public void run() {  //覆写run 方法
//currentThread().getName()取得当前正在运行的线程的名称      
//System.out.println(Thread.currentThread().getName() + "运行");
    }
}

线程的优先级

线程的优先级用数字表示,范围从1到10,默认的是为5
每个线程默认的优先级与创建它的父线程的优先级相同
优先级越高的线程,被执行的顺序就比较靠前,在Thread中存在三个常量:

public final static int MIN_PRIORITY = 1;

public final static int NORM_PRIORITY = 5;

public final static int MAX_PRIORITY = 10;

class MyThread implements Runnable  //实现Runnable接口
{
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

public class Test {
    public static void main(String args[]) {
        Thread t1 = new Thread(new MyThread(), "线程A");
        Thread t2 = new Thread(new MyThread(), "线程B");
        Thread t3 = new Thread(new MyThread(), "线程C");
        t1.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.NORM_PRIORITY);
        t3.setPriority(Thread.MIN_PRIORITY);
        t1.start();
        t2.start();
        t3.start();
    }
}

后台线程

后台线程区别于普通线程,普通线程又可以称为用户线程,只完成用户自己想要完成的任务,不提供公共服务。而有时,我们希望编写一段程序,能够提供公共的服务,保证所有用户针对该线程的请求都能有响应。

仔细来看下后台线程的定义:

指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分。
因此当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台线程。

通过setDaemon(true)来设置该线程为后台线程。

class MyThread implements Runnable{ // 实现Runnable接口
    public void run(){  // 覆写run()方法
        while(true){
            System.out.println(Thread.currentThread().getName() + "在运行。") ;
        }
    }
};
public class Test{
    public static void main(String args[]){
        MyThread mt = new MyThread() ;  // 实例化Runnable子类对象
        Thread t = new Thread(mt,"线程");     // 实例化Thread对象
        t.setDaemon(true) ; // 此线程在后台运行
        t.start() ; // 启动线程
    }
};

线程的中断

一个线程可以被另一个线程中断其操作的状态,使用interrupt()方法。

class MyThread implements Runnable  //实现Runnable接口
{
    public void run() {  //覆写run 方法

        try {
            //sleep方法会出现异常
            System.out.println("1、进入run方法");
            Thread.sleep(6000);     //程序会暂停6000毫秒再执行
            System.out.println("2、已经完成了休眠");
        } catch (InterruptedException e) {
            System.out.println("3、休眠被终止!");
            return;     //返回方法调用处


        }
        System.out.println("4、run方法正常结束");
    }
}

public class Test {
    public static void main(String args[]) {
        MyThread m = new MyThread();  //实例化Runnable子类对象
        Thread t = new Thread(m, "自定义线程");
        t.start();
        try {
            //sleep方法会出现异常
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }

        t.interrupt();
    }
}

终止线程

有三种方法可以使终止线程。
1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
3. 使用interrupt方法中断线程。


参考文档:
1. https://blog.csdn.net/u014290221/article/details/51436710

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/thebigdipperbdx/article/details/79954558
文章标签: Thread jdk1.8
个人分类: concurrent
上一篇MySQL分库分表
下一篇结构型模式--装饰器模式【Decorator Pattern】
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭