一.常见的成员方法:

  • 第三个sleep方法的形参就是指定休眠时间,单位为毫秒,比如传递参数1000,就是休眠1s
  • Java中线程的优先级最小是1,最大是10,默认是5,优先级越大,抢占到CPU的概率越高

二.方法演示:

1.getName方法:

代码:

package com.itheima.a04threadmethod;

public class ThreadDemo {
    public static void main(String[] args) {
        /*演示getName方法:如果没有给线程设置名字,那线程有默认的名字吗?答案是有*/

        //1.创建线程的对象
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();

        //2.开启线程
        t1.start();
        t2.start();
    }
}
package com.itheima.a04threadmethod;

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + "@" + i);
            //此时@前的就是线程的名字
        }
    }
}

运行结果如下:

如上图,

运行结果中@前是有数据的,该数据就是线程默认的名字,

本例中是Thread-0和Thread-1,格式是Thread加-,再加一个序号,序号从0开始,

getName方法的细节:

Ⅰ.如果没有给线程设置名字,线程也是有默认的名字的->格式:Thread-X(X是序号,从0开始的),源码如下:

如上图,是Thread类里的一个空参构造,用this关键字调用了其他的构造,在第三个参数中就是给线程设置名字,前面的Thread-就是固定格式,后面加了一个方法nextThreadNum,nextThreadNum源码如下:

nextThreadNum方法的作用就是变量threadInitNumber不断的自增,然后返回threadInitNumber的值,threadInitNumber一开始默认为0,所以第一个线程默认的序号为0,

注:threadInitNumber++是先参与运行,再自增,所以第一次调用nextThreadNum方法时,里面的threadInitNumber为0并返回,然后自增为1,第二次调用nextThreadNum方法时threadInitNumber为1并返回,然后自增为2。

2.setName方法:

代码:

package com.itheima.a04threadmethod;

public class ThreadDemo {
    public static void main(String[] args) {
        /*演示getName方法:如果没有给线程设置名字,那线程有默认的名字吗?答案是有*/

        //1.创建线程的对象
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();

        /*给线程设置名字*/
        t1.setName("线程1");
        t2.setName("线程2");

        //2.开启线程
        t1.start();
        t2.start();
    }
}
package com.itheima.a04threadmethod;

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + "@" + i);
            //此时@前的就是线程的名字
        }
    }
}

运行结果:

如上图,可以得知两个线程是交替运行的。

3.Thread类的构造方法也是可以给线程命名的:

该构造方法详情如下:

形参是String型,变量名为name,该形参就是给线程设置的名字,

还有一个构造方法是两个形参,如下图:

第一个参数是Runnable接口,所以第一个形参可以传递线程的任务对象,

第二个参数String name就是线程名字。

实例:

如上图,在MyThread的构造方法里命名后,系统报错了,

这是因为现在创建的是MyThread对象,MyThread类虽然是Thread类的子类,但此时只有Thread类里有可以给线程命名的构造方法,由于构造方法不能继承,所以MyThread类里就没有能给线程命名的构造方法,

因此如果子类MyThread想要用父类Thread的构造方法给线程命名该怎么办呢?只需要在子类MyThread里写一个利用super关键字去调用父类的构造方法的方法即可,正确代码如下:

package com.itheima.a04threadmethod;

public class ThreadDemo {
    public static void main(String[] args) {
        /*演示getName方法:如果没有给线程设置名字,那线程有默认的名字吗?答案是有*/

        //1.创建线程的对象
        MyThread t1=new MyThread("飞机");
        MyThread t2=new MyThread("坦克");

        //2.开启线程
        t1.start();
        t2.start();
    }
}
package com.itheima.a04threadmethod;

public class MyThread extends Thread {
    public MyThread() {
    }

    public MyThread(String name) {
        /*super(name)就是访问父类的构造方法*/
        /*该MyThread方法的形参name的值会通过super(name)传递给其父类Thread的构造方法,
        而且传给的是父类中只有一个形参且形参类型为String的构造方法Thread,该构造方法Thread也正是给线程命名的构造方法*/
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + "@" + i);
            //此时@前的就是线程的名字
        }
    }
}

运行结果:

总结:如果要给线程设置名字,可以用setName方法,也可以用构造方法Thread。

3.currentThread方法(静态方法):该方法是空权限修饰符,意味着别的软件包里的类无法直接使用,可以类名.方法名进行调用

演示currentThread方法,现在不开启线程,
直接调用currentThread方法,这时获取到的线程对象是什么呢?
注:currentThread方法的作用是获取当前线程的对象,也就是说哪条线程执行到这个currentThread方法,此时获取到的就是哪条线程的对象->

细节:这个细节不止是currentThread方法的细节,而是整个Java虚拟机的细节, 当JVM虚拟机启动之后,会自动启动多条线程,其中有一条线程就叫做main线程,main线程的作用就是去调用main方法,并执行main方法里的代码,在以前,我们写的所有代码,其实都是运行在main线程当中的。

package com.itheima.a04threadmethod;

public class ThreadDemo {
    public static void main(String[] args) {
        /*演示currentThread方法,现在不开启线程,
        * 直接调用currentThread方法,这时获取到的线程对象是什么呢?
        * 注:currentThread方法的作用是获取当前线程的对象,也就是说
        * 哪条线程执行到这个currentThread方法,此时获取到的就是哪条线程的对象*/
        Thread t = Thread.currentThread();
        //此时这个变量t,就表示执行main方法的线程对象
        String name = t.getName();
        System.out.println(name); //打印结果为main
        /*打印结果为main,这是什么意思呢?
        * 细节:这个细节不止是currentThread方法的细节,而是整个Java虚拟机的细节,
        * 当JVM虚拟机启动之后,会自动启动多条线程,
        * 其中有一条线程就叫做main线程,
        * main线程的作用就是去调用main方法,并执行main方法里的代码,
        * 在以前,我们写的所有代码,其实都是运行在main线程当中的*/
    }
}

4.sleep方法(静态方法):该方法是空权限修饰符,意味着别的软件包里的类无法直接使用,可以类名.方法名进行调用

细节:

  1. 哪条线程执行到这个sleep方法,那么哪条线程就会在这里停留对应的时间
  2. 停留的时间与sleep方法的参数有关->sleep方法的参数:就表示睡眠(停留)的时间,单位是毫秒(例如:1秒=1000毫秒)
  3. 当睡眠(停留)时间结束之后,线程会自动的醒来,继续执行下面的其他代码

例一:

package com.itheima.a04threadmethod;

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        /*细节:
        *  1.哪条线程执行到这个sleep方法,那么哪条线程就会在这里停留对应的时间;
        *  2.停留的时间与sleep方法的参数有关->sleep方法的参数:就表示睡眠(停留)的时间,单位是毫秒
        *     1秒=1000毫秒
        *  3.当睡眠(停留)时间结束之后,线程会自动的醒来,继续执行下面的其他代码*/

        //让main方法进行休眠
        System.out.println("111111");
        Thread.sleep(5000); //让main方法睡眠5s
        System.out.println("222222222"); //睡眠后再执行该语句
        /*运行结果中先运行了输出111111,隔了5s后才输出222222222,
        * 为什么会有这种效果呢?其实就是因为main线程被sleep方法停留了5s,
        * 时间到了之后就会继续执行下面的代码*/
    }
}

例二:

package com.itheima.a04threadmethod;

public class ThreadDemo {
    public static void main(String[] args) {
        /*细节:
        *  1.哪条线程执行到这个sleep方法,那么哪条线程就会在这里停留对应的时间;
        *  2.停留的时间与sleep方法的参数有关->sleep方法的参数:就表示睡眠(停留)的时间,单位是毫秒
        *     1秒=1000毫秒
        *  3.当睡眠(停留)时间结束之后,线程会自动的醒来,继续执行下面的其他代码*/


        //1.创建线程的对象
        MyThread t1=new MyThread("飞机");
        MyThread t2=new MyThread("坦克");

        //2.开启线程
        t1.start();
        t2.start();
        /*最终的运行就是每隔1s打印1次*/
    }
}
package com.itheima.a04threadmethod;

public class MyThread extends Thread {
    public MyThread() {
    }

    public MyThread(String name) {
        /*super(name)就是访问父类的构造方法*/
        /*该MyThread方法的形参name的值会通过super(name)传递给其父类Thread的构造方法,
        而且传给的是父类中只有一个形参且形参类型为String的构造方法Thread,该构造方法Thread也正是给线程命名的构造方法*/
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                Thread.sleep(1000); //停留1000毫秒即1s
                /*此时就不能抛出异常了,只能try,因为父类Thread里的run方法是没有抛出异常的,
                * 父类的run方法没有抛出异常,那么其子类里的run方法就不能抛出异常,子类只能自己try*/
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(getName() + "@" + i);
            //此时@前的就是线程的名字
        }
    }
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐