java 多线程Thread类

Thread类之前在博客简单介绍了下,本篇重点介绍几个常用方法:

先看构造方法:

Thread() 创建新的线程对象

Thread(String name) 基于指定的名字创建一个线程对象

Thread(Runnable target)基于Runnable接口实现类的实例(可以是匿名内部类)创建一个线程对象

Thread(Runnable t,String name) 根据给定的Runnable接口实现类的实例和指定的名字创建一个线程对象

常用属性和方法:

private int priority;线程优先级
private boolean daemon = false;是否是保护线程
public static final int MIN_PRIORITY = 1;最小优先级
public static final int NORM_PRIORITY = 5;中等优先级
public static final int MAX_PRIORITY = 10;最大优先级
synchronized void start() 启动线程
void run() 如果创建线程时使用的是继承Tread类创建的,要重写run方法,线程体放在run方法里
final synchronized void setName(String name) 设置线程名字
final String getName() 获取线程名字,不能在Runnable接口的实现类或者匿名内部类中重写的run方法中调用
static native void yield(); 礼让,暂停当前线程,多个线程(包括当前线程)再次抢占cpu使用权
static native void sleep(long millis) throws InterruptedException;该方法可以使当前线程睡眠,线程睡眠后,里面的任务不会执行,待睡眠时间过后会自动苏醒,从而继续执行任务。参数为毫秒,在run方法中不能抛出该异常,只能捕获该异常,因为Thread类中run方法不能抛出异常,重写的方法不能比父类异常类型大
static void sleep(long millis, int nanos)throws InterruptedException,第一个参数毫秒,第二个参数纳秒,可以设置更精确的睡眠时间
void interrupt()//唤醒睡眠的线程,会抛出InterruptedException异常(好像人睡觉,谁都不希望突然被叫醒)
final void setPriority(int newPriority)//设置线程的优点级,从1到10这10中优先级,10的优先级最高,优先级高的并不是就先执行完,而是cpu会分给它较多的时间去执行
final int getPriority()//获取优先级等级
final void join() throws InterruptedException//让线程A加入,加入后要一次性执行完这个加入的线程A,再接着执行刚才没执行完的线程,继承Thread类的自定义类中重写的run方法中只能捕获该异常,而不能抛出
final void setDaemon(boolean on),设置守护线程,当其他非守护线程都执行完成时,守护线程自动退出,比如java虚拟机的垃圾回收器就是守护线程
final boolean isDaemon()//判断是否为守护线程

以下的演示如果设计到两个类就写一个继承Thread的类写一个匿名内部类

sleep()休眠

public class ThreadSleepTest01 {
    public static void main(String[] args){
            Thread t1=new Thread("t1"){
                @Override
                public void run() {
                    for (int i=0;i<10;i++){
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println( "Thread  "+this.getName()+"will sleep");
                    }
                }
            };
            SleepThread st=new SleepThread("sleepThread");
            t1.start();
            st.start();
    }
}
class SleepThread extends Thread{
    public SleepThread(String name){
        super(name);
    }
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println( this.getName()+" is Sleeping");
        }
    }
}
out:
Thread  t1will sleep
Thread  t1will sleep
Thread  t1will sleep
Thread  t1will sleep
Thread  t1will sleep
sleepThread is Sleeping
sleepThread is Sleeping
sleepThread is Sleeping
sleepThread is Sleeping
sleepThread is Sleeping

结果说明,在SleeoThread线程还在休眠时,Threadt1线程已经执行完毕

interrupt()唤醒,将正在休眠的线程唤醒,会抛出异常

public class ThreadInterruptTest01 {
    public static void main(String[] args){
        SleepInterrupt si =new SleepInterrupt("睡眠唤醒线程");
        si.start();
        si.interrupt();

    }
}
class SleepInterrupt extends Thread{
    public SleepInterrupt(String name){
        super(name);
    }
    @Override
    public void run() {
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i=0;i<10;i++){

            System.out.println(this.getName()+i );
        }
    }
}
out:
java.lang.InterruptedException: sleep interrupted
	at java.base/java.lang.Thread.sleep(Native Method)
	at ThreadMethodTest.SleepInterrupt.run(ThreadInterruptTest01.java:18)
睡眠唤醒线程0
睡眠唤醒线程1
睡眠唤醒线程2
睡眠唤醒线程3
睡眠唤醒线程4
睡眠唤醒线程5
睡眠唤醒线程6
睡眠唤醒线程7
睡眠唤醒线程8
睡眠唤醒线程9

setPriority()方法设置线程的优先级,Thread提供了三个静态int变量,从1到10的共10个等级,线程优先级高的cpu分配给其较多的执行时间

优先级最低:public final static int MIN_PRIORITY = 1;
优先级居中:public final static int NORM_PRIORITY = 5;
优先级最高:public final static int MAX_PRIORITY = 10;

示例:

package ThreadMethodTest;

public class ThreadPriorityTest01 {
    public static void main(String[] args){
        Thread t=new Thread("线程t"){

            @Override
            public void run() {

                for (int i=0;i<100;i++){
                    System.out.println( this.getName()+" : "+i);
                }
            }
        };
        MyThread3 mt3=new MyThread3("线程mt3");
        t.setPriority(2);
        mt3.setPriority(10);
        t.start();
        mt3.start();

    }
}

class MyThread3 extends Thread{
    public MyThread3(String name){
        super(name);
    }
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            System.out.println( this.getName()+" : "+i);
        }
    }
}

yield()礼让,该方法执行时,只是暂停了此线程,但不会保证多个线程(包括当前线程)谁能拿到cpu控制权,优先让其他线程执行,

public class ThreadYieldTest01 {
    public static void main(String[] args){
        Thread t1=new Thread("线程t1"){
            @Override
            public void run() {
                for (int i=0;i<100;i++){
                    System.out.println( this.getName()+" : "+i);
                }
            }
        };
        MyThread4 mt4=new MyThread4("线程mt4");
        t1.start();
        mt4.start();
    }
}
class MyThread4 extends  Thread{
    public MyThread4(String name){
        super(name);
    }
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            if (i%2==0){
                Thread.yield();//礼让,让写的线程执行
            }
            System.out.println(this.getName()+" : "+i );
        }
    }
}
out:
结果太长,不贴出来了,但线程t1先执行完

join()加入线程,当A线程正在执行中加入B线程时,cpu先去执行B线程,B线程执行完再来执行A线程,加入之前时cpu调度执行线程

示例:

public class ThreadJoinTest01 {
    public static void main(String[] args){
        Thread t=new Thread("线程t"){
            @Override
            public void run() {
                for (int i=0;i<100;i++){
                    System.out.println(this.getName()+" : "+i );
                }
                
            }
        };
        MyThread5 mt5=new MyThread5("线程mt5",t);
        t.start();
        mt5.start();
    }
}
class MyThread5 extends Thread{
    Thread t1;
    public MyThread5(String name,Thread t1){
        super(name);
        this.t1=t1;
    }
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            if (i==10){
                try {
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println( this.getName()+" : "+i);
        }
    }
}
out:
结果太长,就不贴出来了
线程mt5执行到i=10时,不再执行,开始执行线程t,等线程t执行完成后,再继续执行mt5

使用两个匿名内部类来演示join方法:

package ThreadMethodTest;

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


    Thread t1=new Thread("线程t1"){
        @Override
        public void run() {
            for (int i=0;i<100;i++){
                System.out.println( this.getName()+" : "+i);
            }
        }
    };
    Thread t2=new Thread("线程t2"){
        @Override
        public void run() {
            for (int i=0;i<100;i++){
                if (i==10){
                    try {
                    //    t1.start(); //如果t1.start放在这里,t2会先打印到9,然后t1开始执行,t1执行完后再执行t2
                        t1.join();

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(this.getName()+" : "+i);
            }
        }
    };
    t1.start();//刚开始执行时两个线程抢占cpu,但当t2的i到10时,开始执行t1线程,执行完t1后才继续执行t2
    t2.start();
}
}

setDaemon(boolean on),设置守护线程

package ThreadMethodTest;

public class ThreadDeamonTest01 {
    public static void main(String[] args){
        MyThread6 mt6=new MyThread6("线程mt6");
        Thread t=new Thread("线程t"){
            @Override
            public void run() {
                for (int i=0;i<100;i++) {
                    System.out.println(this.getName() + "是" + (this.isDaemon() ? "守护线程" : "非守护线程"));
                }
            }
        };
        t.setDaemon(true);
        t.start();
        mt6.start();
    }
}
class MyThread6 extends Thread{

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

    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println( this.getName()+"是"+(this.isDaemon()?"守护线程":"非守护线程"));
        }
    }
}
out:
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程mt6是非守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程
线程t是守护线程

可以看到当非守护线程结束后,守护线程执行了一段时间,还没执行完就不再执行了

参考:http://www.monkey1024.com/javase/670

猜你喜欢

转载自blog.csdn.net/sinat_41132860/article/details/84452302