Day21-2.Thread类

1 Thread类

1.1 获取线程名称

  1. getName() :
    获取线程名称
  2. 特点:
    (1)如果没有给线程设置名称,线程会有一个默认名称
    名字:Thread -x(序号从0开始)
    (2)在子类对象中可以直接调用该方法,用来打印该线程的名称

代码

package demos2;

public class Demo01 {
    public static void main(String[] args) {
//        Thread t1 = new Thread();
//        System.out.println(t1.getName());
//
//        Thread t2 = new Thread();
//        System.out.println(t2.getName());

        //使用匿名内部类创建子类对象
        Thread t3 = new Thread(){
            @Override
            //在子类类型中,重写父类的run方法,表示需要执行的任务
            //因为子类继承了父类的getName方法,所以可以打印名称
            //打印的条件是启动线程
            public void run(){
                System.out.println(getName());
            }
        };
        t3.start();
    }
}

1.2 设置线程名称

  1. setName(String name):给线程对象设置名称
  2. Thread(String name):通过构造给线程命名
  3. Thread(Runnable target, String name):在接收一个任务的同时给线程命名
  4. 注意:
    (1)如果想要给子类线程对象命名,可以使用从父类继承的set方法
    也可以使用构造方法,但是子类需要自己定义有参构造赋值

代码

package demos2;

public class Demo02 {
    public static void main(String[] args) {
        Thread t1 = new Thread();
        System.out.println(t1.getName());
        t1.setName("新线程001");
        System.out.println(t1.getName());

        Thread t2 = new Thread("新线程002");
        System.out.println(t2.getName());

        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("新线程执行的任务");
            }
        };
        Thread t3 = new Thread(r,"新线程003");
        System.out.println(t3.getName());
    }
}
代码2
package demos2;

public class Demo03 {
    public static void main(String[] args)  {
        MyThread2 mt = new MyThread2("新线程");
        mt.start();
    }
}
//子类定义有参构造,给属性赋值
class MyThread2 extends Thread{
    public void run(){
        System.out.println(getName());
    }

    public MyThread2(String name){
        super(name);
    }
}

1.3 获取线程对象

  1. 方法:currentThread()
  2. 特点:
    (1)将来哪一个线程执行这个方法,就返回对应的线程对象
    (2)是一个静态方法

代码

package demos2;

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

        MyTask mt = new MyTask();
        Thread t1 = new Thread(mt,"线程01");
        Thread t2 = new Thread(mt,"线程02");
        t1.start();
        t2.start();
    }
}
//类型是用来定义任务
class MyTask implements Runnable{
    @Override
    public void run() {
        System.out.println("新线程需要执行的任务");
        //将来哪一个线程执行该任务,就打印对应线程的线程名称
        //想要去打印线程名称;通过线程对象.getName();
        //哪一条线程执行该方法,就返回对应的线程对象
        Thread t = Thread.currentThread();
        System.out.println(t.getName());
    }
}

1.4 练习

  1. 获取main线程的线程名称
  2. 获取垃圾回收线程名称

代码

package demos2;

public class Test01 {
    public static void main(String[] args) {
        //获取主线程名称
        //获取主线程的线程对象
        Thread t = Thread.currentThread();
        System.out.println(t.getName());

        //获取垃圾回收线程的线程名称
        //获取垃圾回收线程的线程对象
        new Demo();
        System.gc();
    }
}
class Demo{
    //当前类的对象被回收时,会有垃圾回收线程执行该方法
    @Override
    protected void finalize() throws Throwable {
        //该方法是由垃圾线程执行,返回的垃圾线程的对象
        Thread t = Thread.currentThread();
        //返回垃圾线程的名称
        System.out.println(t.getName());
    }
}

1.5 线程休眠

  1. Thread.sleep(long time):让执行这段代码的线程休息一会
    参数time:表示线程休息的时间 毫秒为单位
  2. 特点:
    哪一个线程执行该方法,就让对应的线程进行休眠
  3. 注意事项:
    (1)如果在一个普通的方法中,使用sleep(),可以声明异常也可以捕获异常
    (2)如果在一个重写的方法中,使用sleep(),只能对该异常进行捕获处理,不能声明
    (3)使用该方法,会出现一个编译时异常:InterruptedException 线程中断异常
    当线程休眠被中断时,会抛出该异常
    (4)interrupt可以强制唤醒正在休眠的线程(一旦休眠的线程被强制唤醒,会出现线程中断异常)

代码1

package demos2;

public class Demo05 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new MyTask3());
        t.start();
    }
}

class MyTask3 implements Runnable{
    @Override
    public void run() {
        for(int i = 10;i >= 1;i--){
            System.out.println(i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

代码2

package demos2;

public class Demo06 {
    public static void main(String[] args) throws InterruptedException {

        MyTask4 mt = new MyTask4();
        Thread t = new Thread(mt);
        t.start();

        t.sleep(5000);//Thread.sleep();
        //哪一个线程执行该方法,就让哪一个线程休眠
        //虽然休眠是t线程调用的,但是在主线程中执行的该方法,是主线程休眠
        //总结:sleep()方法不是谁调用,谁就休眠
        //      谁执行谁休眠
    }
}
class MyTask4 implements Runnable{
    @Override
    public void run() {
        for(int i = 10;i >= 1;i--){
            System.out.println(i);
        }
    }
}

代码3

package demos2;

public class Demo07 {
    public static void main(String[] args) throws InterruptedException {

        MyThread1 mt = new MyThread1();
        mt.start();

        //在5秒之后,强制唤醒正在休眠的线程(休眠中断)
        Thread.sleep(5000);
        //强制唤醒线程休眠
        mt.interrupt();
    }
}
class MyThread1 extends Thread{
    @Override
    public void run(){
        System.out.println("新线程开始执行了.....");
        System.out.println("新线程又开始休眠了,预计休眠的时间为:1年...");
        try {
            Thread.sleep(1000*60*60*24*365);
        } catch (InterruptedException e) {
            System.out.println("该线程睡觉被意外吵醒了!!!");
        }
        System.out.println("新线程任务执行结束了...");
    }
}

1.6 守护线程

  1. 概念:保护其他线程能够正常运行的线程就是守护线程。
  2. 方法
函数名Value
setDaemon(boolean on)将当前线程对象设置为指定线程,参数为true为守护线程否 则为非守护线程。
isDaemon()判断当前对象是否是一个守护线程
  1. 注意:
    (1)自定义的线程对象都是非守护线程(用户线程)
    (2)如果守护线程要保护的用户线程结束了,守护线程会跟着直接结束
    (3)如果一个守护线程需要保护多条用户线程,如果多条用户线程全部结束,守护线程才结束,如果多条用户线程有一条是执行的,守护线程不会结束

代码

package demos2;

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

        Thread t1 = new Thread(){
            public void run(){
                while(true){
                    System.out.println(getName() + "...正在执行任务");
                }
            }
        };
        t1.setName("新线程01");
        //将t1线程设置为守护线程
        t1.setDaemon(true);
        //判断t1线程是否是守护线程
        System.out.println(t1.isDaemon());
        //启动守护线程,(随着主线程的结束,跟着结束)
        t1.start();
    }
}

1.7 练习

(1)判断main线程是否是一个守护线程
(2)判断垃圾回收线程是否是一个守护线程

代码

public class Demo01 {
    public static void main(String[] args) {
        Thread t = Thread.currentThread();
        System.out.println(t.isDaemon());
        new p();
        //强制调用垃圾回收函数
        System.gc();
    }
}
class p {
    @Override
    //重写finalize函数,获取垃圾回收线程是否是守护线程
    protected void finalize() throws Throwable {
        Thread t = Thread.currentThread();
        System.out.println(t.isDaemon());
    }
}

1.8 设置线程优先级

  1. 线程优先级概念:
    自定义的线程都有一个默认的优先级,默认的优先级都是相同,被cpu执行的机会相同
    可以设置线程的优先级,线程优先级高的线程,被cpu先执行机会高
    线程优先级低的线程,被cpu先执行的机会低

  2. 设置优先级的方法:
    setPriority(int newPriority) :设置线程优先级
    参数:表示优先级的级别:从低到高1 ---- 10
    如果不给线程设置优先级:都是默认的:5

  3. 静态常量:
    static int MAX_PRIORITY
    线程可以拥有的最大优先级。
    static int MIN_PRIORITY
    线程可以拥有的最小优先级。
    static int NORM_PRIORITY
    分配给线程的默认优先级。

代码

package demos2;

public class Demo09 {
    public static void main(String[] args) {
        Thread t1 = new Thread(){
            public void run(){
                for(int i = 1;i <= 100;i++){
                    System.out.println(getName() +"...." + i);
                }
            }
        };
        Thread t2 = new Thread(){
            public void run(){
                for(int i = 1;i <= 100;i++){
                    System.out.println(getName() +"--------------" + i);
                }
            }
        };
        t1.setName("线程01");
        t2.setName("线程02");
        //设置线程优先级为最低:每一次被cpu执行的概率最小的
        t1.setPriority(Thread.MAX_PRIORITY);
        //设置线程优先级为最高:每一次被cpu执行的概率最高的
        t2.setPriority(Thread.MIN_PRIORITY);
        t1.start();
        t2.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值