Java 中线程的常用方法

目录

1. 构造方法

2 .所有方法

3. 常用方法和对应代码演示

 3.1 CurrentThread():  这是一个 静态的方法---- statuc Thread

 3.2 Thread.getId()         ----------- long

3.3 sleep(long millis) :     -   --------           static void

实现计时器--使用sleep(1000)

3.4 setName(String name) 和 getName()

3.5 isAlive()

 3.6  start()  ------------ void

3.7 yield () 

3.8 setPriority(int newPriority)

 3.9 interrupt()

3.11 setDaemon() 



1. 构造方法

Thread()

分配一个新的 Thread对象。

Thread(Runnable target)

分配一个新的 Thread对象。

Thread(Runnable target, String name)

分配一个新的 Thread对象。

Thread(String name)

分配一个新的 Thread对象。

Thread(ThreadGroup group, Runnable target)

分配一个新的 Thread对象。

Thread(ThreadGroup group, Runnable target, String name)

分配一个新的 Thread对象,使其具有 target作为其运行对象,具有指定的 name作为其名称,属于 group引用的线程组。

Thread(ThreadGroup group, Runnable target, String name, long stackSize)

分配一个新的 Thread对象,以便它具有 target作为其运行对象,将指定的 name正如其名,以及属于该线程组由称作 group ,并具有指定的 堆栈大小

Thread(ThreadGroup group, String name)

分配一个新的 Thread对象。

2 .所有方法

static intactiveCount()

返回当前线程的thread group及其子组中活动线程数的估计。

voidcheckAccess()

确定当前正在运行的线程是否有权限修改此线程。

protected Objectclone()

将CloneNotSupportedException作为线程抛出无法有意义地克隆。

intcountStackFrames()已弃用

此呼叫的定义取决于suspend() ,它已被弃用。 此外,此呼叫的结果从未明确。

static ThreadcurrentThread()

返回对当前正在执行的线程对象的引用。

voiddestroy()已弃用

这种方法最初是为了销毁这个线程而没有任何清理。 它所持有的任何监视器都将保持锁定。 但是,该方法从未实现。 如果要实施,那么它将是suspend()的方式是僵死的 。 如果目标线程在销毁时保护关键系统资源的锁,则无法再次访问该资源。 如果另一个线程曾尝试锁定此资源,将导致死锁。 这种僵局通常表现为“冻结”过程。 有关详细信息,请参阅Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

static voiddumpStack()

将当前线程的堆栈跟踪打印到标准错误流。

static intenumerate(Thread[] tarray)

将当前线程的线程组及其子组中的每个活动线程复制到指定的数组中。

static Map<Thread,StackTraceElement[]>getAllStackTraces()

返回所有活动线程的堆栈跟踪图。

ClassLoadergetContextClassLoader()

返回此Thread的上下文ClassLoader。

static Thread.UncaughtExceptionHandlergetDefaultUncaughtExceptionHandler()

返回当线程由于未捕获异常突然终止而调用的默认处理程序。

longgetId()

返回此线程的标识符。

StringgetName()

返回此线程的名称。

intgetPriority()

返回此线程的优先级。

StackTraceElement[]getStackTrace()

返回表示此线程的堆栈转储的堆栈跟踪元素数组。

Thread.StategetState()

返回此线程的状态。

ThreadGroupgetThreadGroup()

返回此线程所属的线程组。

Thread.UncaughtExceptionHandlergetUncaughtExceptionHandler()

返回由于未捕获的异常,此线程突然终止时调用的处理程序。

static booleanholdsLock(Object obj)

返回 true当且仅当当前线程在指定的对象上保持监视器锁。

voidinterrupt()

中断这个线程。

static booleaninterrupted()

测试当前线程是否中断。

booleanisAlive()

测试这个线程是否活着。

booleanisDaemon()

测试这个线程是否是守护线程。

booleanisInterrupted()

测试这个线程是否被中断。

voidjoin()

等待这个线程死亡。

voidjoin(long millis)

等待这个线程死亡最多 millis毫秒。

voidjoin(long millis, int nanos)

等待最多 millis毫秒加上 nanos纳秒这个线程死亡。

voidresume()已弃用

该方法仅用于与suspend()一起使用,因为它是死锁倾向的,因此已被弃用。 有关详细信息,请参阅Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

voidrun()

如果这个线程使用单独的Runnable运行对象构造,则调用该Runnable对象的run方法; 否则,此方法不执行任何操作并返回。

voidsetContextClassLoader(ClassLoader cl)

设置此线程的上下文ClassLoader。

voidsetDaemon(boolean on)

将此线程标记为 daemon线程或用户线程。

static voidsetDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

设置当线程由于未捕获的异常突然终止而调用的默认处理程序,并且没有为该线程定义其他处理程序。

voidsetName(String name)

将此线程的名称更改为等于参数 name

voidsetPriority(int newPriority)

更改此线程的优先级。

voidsetUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

设置当该线程由于未捕获的异常而突然终止时调用的处理程序。

static voidsleep(long millis)

使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。

static voidsleep(long millis, int nanos)

导致正在执行的线程以指定的毫秒数加上指定的纳秒数来暂停(临时停止执行),这取决于系统定时器和调度器的精度和准确性。

voidstart()

导致此线程开始执行; Java虚拟机调用此线程的run方法。

voidstop()已弃用

这种方法本质上是不安全的。 使用Thread.stop停止线程可以解锁所有已锁定的监视器(由于未ThreadDeath ThreadDeath异常在堆栈中ThreadDeath的自然结果)。 如果先前受这些监视器保护的任何对象处于不一致的状态,则损坏的对象将变得对其他线程可见,可能导致任意行为。 stop许多用途应该被替换为只是修改一些变量以指示目标线程应该停止运行的代码。 目标线程应该定期检查此变量,如果变量表示要停止运行,则以有序方式从其运行方法返回。 如果目标线程长时间等待(例如,在interrupt变量上),则应该使用interrupt方法来中断等待。 有关详细信息,请参阅Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

voidstop(Throwable obj)已弃用

该方法最初设计为强制线程停止并抛出一个给定的Throwable作为例外。 它本质上是不安全的(有关详细信息,请参阅stop() ),此外还可用于生成目标线程未准备处理的异常。 有关详细信息,请参阅Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

voidsuspend()已弃用

这种方法已被弃用,因为它本身就是死锁的。 如果目标线程在挂起时保护关键系统资源的监视器上的锁定,则在目标线程恢复之前,线程不能访问该资源。 如果要恢复目标线程的线程在调用resume之前尝试锁定此监视器, resume导致死锁。 这种僵局通常表现为“冻结”过程。 有关详细信息,请参阅Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

StringtoString()

返回此线程的字符串表示,包括线程的名称,优先级和线程组。

static voidyield()

对调度程序的一个暗示,即当前线程愿意产生当前使用的处理器。 

以上摘自文档 

3. 常用方法和对应代码演示

 3.1 CurrentThread():  这是一个 静态的方法---- statuc Thread

  • 返回当前正在执行线程对象的引用。
  • 在JAVA中,任何一段代码都是执行在某一个线程当中,执行当前代码的线程就是当前线程。
  • 同一段代码可以被不同执行,因此当前线程是相对的,Thread.currentThread() 方法返回的代码在实际运行的线程对象。
package stu.my.cdn.threadmethod;

public class SubThread1 extends Thread{
    public SubThread1() {
        System.out.println("构造方法打印当前线程名称:"+Thread.currentThread().getName());
    }

    @Override
    public void run() {
        System.out.println("run 方法打印当前线程的名称:"+Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        System.out.println("main 方法中打印当前线程:" + Thread.currentThread().getName());

        SubThread1 subThread1 = new SubThread1();
        subThread1.start(); //启动子线程
    }
}

 因为在main线程中构造了子线程的构造方法,所以构造方法在当前 main 线程执行。

 3.2 Thread.getId()         ----------- long

  • 获得线程的唯一标识。
  • 线程ID是创建此线程时生成的正数long号。
  • 线程ID是唯一的,并且在其生命周期内保持不变。 当线程被终止时,该线程ID可以被重用。
package stu.my.cdn.threadmethod;

public class GetId extends Thread{
    @Override
    public void run() {
        System.out.println("Thread name = " + Thread.currentThread().getName()
        + " id == " + this.getId());
    }

    public static void main(String[] args) {
        System.out.println("Thread name = " + Thread.currentThread().getName()
                + " id == " + Thread.currentThread().getId());

        // 子线程 id
        for(int i =  1; i < 10; i++){
            new GetId().start();
        }
    }

}

    注意:

        某个编号的线程运行结束后,该编号可能被后续创建的线程使用。

        重启 JVM 后,同一个线程编号可能不一样。

3.3 sleep(long millis) :     -   --------           static void

  • 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。
  • 线程不会丢失任何显示器的所有权。
  • 当前线程就是 Thread.currentThread() 返回的线程。
package stu.my.cdn.threadmethod.sleep;

public class Sleep extends  Thread{

    @Override
    public void run() {
        System.out.println("run_begin"+System.currentTimeMillis());
        try {
            sleep(500);
            System.out.println("run_end" + System.currentTimeMillis());
        } catch (InterruptedException e) {
            // 在子线程的 run 方法中,如果有受检异常(编译时异常)需要处理,只有选择捕获异常,不能抛出异常
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Sleep sleep = new Sleep();
        System.out.println("main_begin---"+System.currentTimeMillis());
        sleep.start();  // 开启新的线程
        // sleep.run();    // 在main线程中调用实例的run() ,没有开启新的线程
        System.out.println("main_end---"+System.currentTimeMillis());
    }
}

   因为子线程使用了sleep休眠了500ms,所以main线程先执行结束了程序。

实现计时器--使用sleep(1000)

package stu.my.cdn.threadmethod.sleep;

public class SimplerTimer {
    public static void main(String[] args) {

        int remaining = 60;     // 从 60 秒开始计时
        // 读取 main 方法参数
        if(args.length == 1){
            remaining = Integer.parseInt(args[0]);
        }

        while(true){
            System.out.println("remaining:" + remaining );
            remaining--;
            if(remaining < 0 ){
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Done!!!");
    }
}

3.4 setName(String name) 和 getName()

setName(String name)

  • 将此线程的名称更改为等于参数name
  • 首先调用这个线程的checkAccess方法,没有参数。 这可能会导致投掷SecurityException

getName()

  • 返回此线程的名称。

3.5 isAlive()

  •  测试这个线程是否活着。
  • 如果一个线程已经启动并且尚未死亡,那么线程是活着的。
package stu.my.cdn.threadmethod;

public class IsAlive extends Thread{
    @Override
    public void run() {
        System.out.println("run");
    }

    public static void main(String[] args) {
        IsAlive isAlive = new IsAlive();
        System.out.println("begin==》" + isAlive.isAlive());
        isAlive.start();
        System.out.println("end == > " + isAlive.isAlive());
    }
}

   因为刚开始线程还未启动,所以线程处于为活动状态,所以返回 false。而当执行start方法,线程开始活动,则为true

 3.6  start()  ------------ void

  • 导致此线程开始执行; Java虚拟机调用此线程的run方法。
  • 结果是两个线程同时运行:当前线程(从调用返回到start方法)和另一个线程(执行其run方法)。
  • 不止一次启动线程是不合法的。 特别地,一旦线程完成执行就可能不会重新启动。

3.7 yield () 

  • 对调度程序的一个暗示,即当前线程愿意产生当前使用的处理器。 调度程序可以自由地忽略这个提示。
  • 产量是一种启发式尝试,以改善否则会过度利用CPU的线程之间的相对进度。 其使用应与详细的分析和基准相结合,以确保其具有预期的效果。
  • 主要作用是放弃当前线程占有的 cpu 资源
package stu.my.cdn.threadmethod;

public class Yiled extends Thread {
    @Override
    public void run() {
        long begin = System.currentTimeMillis();
        long sum = 0;
        for(int i = 1; i < 100000; i ++){
            sum += i;
            Thread.yield();     // 线程让步,放弃 CPU 资源
        }
        long end = System.currentTimeMillis();
        System.out.println("run 用时:" + (end - begin));
    }

    public static void main(String[] args) {
        Yiled yiled = new Yiled();
        yiled.start();
        long begin = System.currentTimeMillis();
        long sum = 0;
        for(int i = 1; i < 100000; i ++){
            sum += i;
        }
        long end = System.currentTimeMillis();
        System.out.println("main方法用时:" + (end - begin));
    }
}

    使用 yield() 方法,放弃了当前 CPU 占有资源。

3.8 setPriority(int newPriority)

  • 设置线程的优先级
  • java 线程的优先级取值范围是 1 ~ 10 ,如果超出这个范围会抛出异常 IllegalArgumentException
  • 在操作系统中,优先级较高的线程获得 CPU 的资源越多

  • 线程优先级本质上只是给线程调度器一个提示信息,以便于调度器决定先调度那些线程,注意不能保证优先级高的程序先运行。

  • JAVA 优先级设置不当,或者滥用,可能会导致某些线程永远无法得到运行,既产生了线程饥饿。

package stu.my.cdn.threadmethod;

public class SetPriority extends Thread{

    @Override
    public void run() {
        long begin = System.currentTimeMillis();
        int sum = 0 ;
        for(int i = 0; i < 1000000000; i++){
            sum += i;
        }
        long end = System.currentTimeMillis();
        System.out.println("end- begin ==" + (end-begin));
    }

    public static void main(String[] args) {
        SetPriority setPriority1 = new SetPriority();
        setPriority1.setPriority(1);    // 设置优先级,优先级越高,获得CPU 的资源越多
        setPriority1.start();

        SetPriority setPriority2 = new SetPriority();
        setPriority2.setPriority(10);   // 优先级高,执行的越快
        setPriority2.start();
    }
}

 3.9 interrupt()

  • 中断这个线程
  • 注意调用 interrupt() 方法仅仅是在当前线程打一个停止标志,并不是真正的停止线程。

3.10 interrupted()

  • 测试当前线程是否被中断。
  • 该方法可以清除线程的中断状态
package stu.my.cdn.threadmethod;

public class Interrupt extends Thread {
    @Override
    public void run() {
        for(int i = 1; i < 10; i++){
            System.out.println("sub thread ---> "+ i);
            if(this.isInterrupted()){
                System.out.println("当前线程中断标志为 true ,我要退出了");
                // break; 中断循环
                return; // 结束当前线程的执行
            }
        }
    }

    public static void main(String[] args) {
        Interrupt interrupt = new Interrupt();
        interrupt.start();      // 开启线程

        // 当前main线程打印
        for (int i = 0; i < 10; i++){
            System.out.println("main == >" + i);
        }

        // 中断子线程
        interrupt.interrupt();      // 仅仅是给子线程标记
    }
}

  对应每次执行结果不一,因为 interrupted() 可以清除线程的终断状态。CPU 在对于这么点程序,来回调度速度太快。

3.11 setDaemon() 

  • JAVA 的线程分为用户线程和守护线程
  • 守护线程是为其它线程提供服务的线程,如垃圾回收器(GC) 就是一个典型的守护线程。
  • 守护线程不能单独运行,当 JVM 中没有了其它的用户线程,只有了守护线程的时候,守护线程就会自动销毁,JVM 退出。
package stu.my.cdn.threadmethod;

public class SetDaemon extends Thread {
    @Override
    public void run() {
        while(true){
            System.out.println("sub thread......");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 设置线程为守护线程
     */
    public static void main(String[] args) {
        SetDaemon setDaemon = new SetDaemon();
        // 设置线程为守护线程
        setDaemon.setDaemon(true);  // 设置守护线程一定要在线程启动前
        setDaemon.start();

        for(int i = 1; i < 10; i++){
            System.out.println("mian== "+ i);
        }

        // main 线程结束,守护线程 setDaemon 也就销毁了
    }
}

   🤔🤔🤔🤔当用户线程完成之后,守护线程便自动终止。

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你困了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值