多线程复习(四)线程中一些的方法

1.3.2 setName()/getName()

thread.setName(线程名称),设置线程名称 thread.getName() 返回线程名称 通过设置线程名称有有助于程序的调试,提高程序的可读性,建议为每个线程都设置一个能够体现线程功能的名称

1.3.3isAlive()

thread.isAlive判断当前线程是否处于活动状态。 活动状态:线程以启动并且未终止

主线程

public class Test {
    public static void main(String[] args) {
        SubThread subThread = new SubThread();
        //启动相册线程之前false
        System.out.println("begin=="+subThread.isAlive());
        subThread.start();
        //这个的结果不一定如果子线程结束就会返回false,如果结束就会返回true
        System.out.println("end=="+subThread.isAlive());
    }
}

子线程

public class SubThread extends Thread {
    @Override
    public void run() {
        System.out.println("run方法,isAlive"+this.isAlive());
    }
}

运行结果

begin==false
end==true //这个结果不一定
run方法,isAlivetrue

1.3.4 sleep()

Thread.sleep(millis);让当前线程休眠指定的毫秒数 当前线程是指Thread.currentThread()返回的线程 主线程

public class Test {
    public static void main(String[] args) {
        SubThread subThread = new SubThread();
        System.out.println("main_begin="+System.currentTimeMillis());
        subThread.start();
        System.out.println("main_end="+System.currentTimeMillis());
    }
}

子线程

public class SubThread  extends Thread{
    @Override
    public void run() {
        System.out.println("run threadname="+Thread.currentThread().getName()+"begin="+System.currentTimeMillis());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            //在子线程的run方法中,如果有受检异常(编译时异常)需要处理,只有选则捕获异常,不能抛出处理
            e.printStackTrace();
        }
        System.out.println("run threadname="+Thread.currentThread().getName()+"end="+System.currentTimeMillis());
    }
}

运行结果

main_begin=1660491805852
main_end=1660491805852
run threadname=Thread-0begin=1660491805853
run threadname=Thread-0end=1660491808854

简易的计时器

/*
* 使用线程休眠Thread.sleep完成一个简易的计时器
* */
public class SimpleTimer {
    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!!!");
    }
}

1.3.5 getId()

thread.getId()可以获得线程的唯一标识

注意: 某个编号的线程运行结束后,该编号可能被后续创建的线程使用。 重启JVM后,同一个线程可能不一样

主线程

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

        System.out.println("main name = "+Thread.currentThread().getName());
        System.out.println( "id =="+ Thread.currentThread().getId());

        //子线程的id
        for (int i = 0; i < 3; i++) {
            new SubThread().start();
        }
    }
}

子线程

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

运行结果

main name = main
id ==1
thread name = Thread-0
id ==12
thread name = Thread-1
id ==13
thread name = Thread-2
id ==14

1.3.6 yield()

Thread.yield()方法的作用是放弃当前的CPU资源

主线程

public class Test {
    public static void main(String[] args) {
        SubThread subThread = new SubThread();
        subThread.start();
        long begin = System.currentTimeMillis();
        int sum=0;
        for (int i = 0; i < 10000000; i++) {
            sum=+i;
        }
        long end = System.currentTimeMillis();
        System.out.println("main用时"+(end-begin));
    }
}

子线程

public class SubThread extends Thread {
    @Override
    public void run() {
        long begin = System.currentTimeMillis();
         int sum=0;
        for (int i = 0; i < 10000000; i++) {
            sum=+i;
            Thread.yield();//线程让步,放弃CPU执行权
        }
        long end = System.currentTimeMillis();
        System.out.println("用时"+(end-begin));
    }
}

运行结果,如果子线程不让步的话,两个线程用时会差不多

main用时1
用时8505

1.3.7 setPrioriy()

thread.setPriority(num);设置线程的优先权

java线程的优先权取值范围是1~10如果超出这个范围会抛出异常

在操作系统中,优先级较高的线程获得CPU的资源越多

线程优先级本质上是只是给线程调度器一个提示信息,以便于调度器决定先调度那些线程,

注意不能保证优先级高的线程先运行

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

线程的优先级并不是设置的越高越好,一般情况下使用普通的优先级即可,即在开发时不必设置线程的优先级

线程的优先级具有继承性,如果在A线程中创建了B线程,则B的优先级与A优先级一样

主线程

public class Test {
    public static void main(String[] args) {
        SubThread subThread = new SubThread();
        subThread.setPriority(1);


        SubThreadII subThreadII = new SubThreadII();
        subThreadII.setPriority(10);
         
        subThread.start();
        subThreadII.start();
    }
}

子线程一

public class SubThread extends Thread{
    @Override
    public void run() {
        int sum=0;
        for (int i = 0; i < 1000000000; i++) {
            sum=+i;
        }
        System.out.println("子线程一");
    }
}

子线程二

public class SubThreadII extends Thread {
    @Override
    public void run() {
        int sum=0;
        for (int i = 0; i < 1000000000; i++) {
            sum=+i;
        }
        System.out.println("子线程二");
    }
}

运行结果

子线程二
子线程一

1.3.8 interrupt()

中断线程

注意:调用interr()方法仅仅是在当前线程打一个停止标志,并不是真正的停止线程

主线程

public class Test {
    public static void main(String[] args) {
        SubThread subThread = new SubThread();
        subThread.start();//开启子线程

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

        //中断子线程
        subThread.interrupt();
    }
}

子线程         

public class Test {
    public static void main(String[] args) {
        SubThread subThread = new SubThread();
        subThread.start();//开启子线程

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

        //中断子线程
        subThread.interrupt();
    }
}

运行结果

main==>0
sub==>0
sub==>1
sub==>2
sub==>3
sub==>4
main==>1
main==>2
sub==>5
main==>3
main==>4
main==>5
main==>6
main==>7
main==>8
main==>9
sub==>6
sub==>7
sub==>8
sub==>9

由运行结果我们可以看出,虽然在main线程结束以后使用了 subThread.interrupt();但是子线程并没有结束

我们可以结合isInterrupted()方法来手动中断线程

子线程

public class SubThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            //判断线程的中断标志
            if(this.isInterrupted()){
                System.out.println("线程中断");
                break;//中断循环
            }
            System.out.println("sub==>"+i);
        }
    }
}

运行结果

main==>0
main==>1
main==>2
main==>3
main==>4
main==>5
sub==>0
sub==>1
main==>6
main==>7
main==>8
main==>9
sub==>2
线程中断

1.3.9 setDaemon()

java中的线程分为用户线程和守护线程

守护线程是为其他线程提供服务的线程,如垃圾回收器,就是一个典型的守护线程。

守护线程不能单独运行,当一个JVM只剩下守护线程的时候,守护线程就会自动销毁,JVM会退出

主线程

public class Test {
    public static void main(String[] args) {
        SubDaemonThread subDaemonThread = new SubDaemonThread();
        subDaemonThread.setDaemon(true);//设置守护线程的代码要在启动前
        subDaemonThread.start();

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

子线程

public class SubDaemonThread extends Thread {
    @Override
    public void run() {
        while (true){
            System.out.println("守护线程");
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果

0
1
2
3
4
5
6
7
8
9
守护线程
//为什么在主线程结束之后会有守护线程执行?
//因为销毁线程需要时间

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值