Thread类常见的使用方法

目录

一、thread的常见的创建方法

二、Thread的几个常见属性以及如何启动一个线程

三、线程的常用方法

        1、中断线程

        2、等待线程

        3、获取当前线程引用

        4、休眠当前线程


一、thread的常见的创建方法

        1、第一种是在进程里面用Thread类直接重写run方法

ublic static void main(String[] args) throws InterruptedException {
        //第一种写法,run直接写在Thread并且用{}包含
        Thread t=new Thread(){
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();
    }

        2、第二种是创建一个新的类来继承Thread然后直接实例化再调用

class MyThread extends Thread{
    @Override
    public void run() {
        while(true){
            System.out.println("hello Thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程办法之一——继承thread
        Thread t=new MyThread();
        t.start();
       
    }
}

        3、第三种是先创建Runnable类,然后把Runnable作为参数写进Thread里面,如下:

        

public static void main(String[] args) throws InterruptedException {
        //第三种线程写法,写在Runnable里面,外面调用
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("hello runnable");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        Thread t=new Thread(runnable);
        t.start();

    }

        4、第四种写法,和第二种有点大同小异,就是创建一个类来继承Runnable接口,然后作为参数写进Thread里面,如下:

        

class MyRunnable implements Runnable{

    @Override
    public void run() {
        while(true){
            System.out.println("hello runnable");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) throws InterruptedException {
          //第二种写线程办法Runnable
           Runnable runnable=new MyRunnable();
           Thread t=new Thread(runnable);
           t.start();
          
    }
}

        5、最后一种是匿名内部类的写法,也是用的最多的写法,代码演示如下:

public static void main(String[] args) throws InterruptedException {
        //线程的第五种写法,匿名写法
        Thread t=new Thread(()->{
            while (true) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
       
    }

        我们能大概了解Thread如何创建,其中Runnable的写法可以更好的解耦合,但用的最多的是匿名内部类的写法,因为这种写法比较方便。

二、Thread的几个常见属性以及如何启动一个线程

        1、第一个常见的属性就是ID,在线程中的方法是getId(),顾名思义,id是线程的唯一标识,不同的线程不会重复

        2、第二个属性是名称,方法是getName(),可以得到线程的名称

        3、第三个属性是状态,方法是getState(),可以得到线程得状态,下列是状态表。

        

状态名称解释
NEW
安排了工作,还未开始行动
RUNNABLE
可工作的.又可以分成正在工作中和即将开始工作;这几个都表示排队等着其他事情
WAITING
这几个都表示排队等着其他事情
TIMED_WAITING
这几个都表示排队等着其他事情
TERMINATED
工作完成了

        4、第四个属性是优先级,方法是getPriority(),可以得到线程优先级

        5、第五个属性是判断是否为后台线程(守护线程),即主线程结束就结束,方法为isDaemon();

        6、第六个属性是判断是否存活,方法是isAlive(),返回的是boolean值,存活为true,反之false。

        7、第七个属性是判断是否被中断,方法为isInterrupted(),返回得也是Boolean值

        8、启动一个线程是start。

 public static void main(String[] args) {
        Thread t1=new Thread(()->{
            for (int i = 0; i < 3; i++) {
                System.out.println("em");
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        t1.start();
        System.out.println(t1.getId());
        System.out.println(t1.getName());
        System.out.println(t1.getState());
        System.out.println(t1.getPriority());
        System.out.println(t1.isDaemon());
        System.out.println(t1.isAlive());
        System.out.println(t1.isInterrupted());
    }

         结果如下:

三、线程的常用方法

        1、中断线程

        中断线程的方法一般使用线程中interrupt的方法中断,具体案例如下:

        

public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("hello world");
                try {
                    //线程每次执行都阻塞1秒
                    Thread.sleep(1000);
                } catch (InterruptedException e) { 
                   throw new RuntimeException(e);
                 break;
                //加上break就是立刻终止
                //不写东西就是不终止
                //catch种先执行一些其他逻辑再break,就是稍后终止
             }
         }
        System.out.println("t结束");
     });
    t.start();
    Thread.sleep(3000);
    System.out.println("main线程尝试终止t线程");
    t.interrupt();
    System.out.println(t.isInterrupted());
}

        打印结果如下:

        三秒后线程被中断,线程也就结束了。

        2、等待线程

        等待线程我们用的是join的方法,当要注意的是,join有三种用法:第一种是没有参数的,也就是要等待这个线程结束,第二种是只有一个参数的,就是等待这个线程,最多等多少毫秒,第三种是俩个参数的,比较少用,也是等待线程最多时间,第一个参数是毫秒,第二个参数是纳秒。

        我们以俩个参数作为例子。

public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            for (int i = 0; i < 3000; i++) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("t线程结束");
        });
        t.start();
        t.join(3000,500);//第一个参数是毫秒,第二个参数是纳秒
        System.out.println("main线程结束");
    }

        打印结果如下:

        在等待了3秒几的时候主线程就继续执行了,不再等待了,而如果没有参数,那么主线程就需要继续等待3000多秒才能结束。

        3、获取当前线程引用

        获取当前线程的引用用的是currentThread的方法,然后可以获取该线程的名字。

public static void main(String[] args) {
 Thread thread = Thread.currentThread();
 System.out.println(thread.getName());
 }

        打印结果如下:

        我们可以知道该线程的引用是main。

        4、休眠当前线程

        休眠线程一般用俩种,第一种是sleep()方法,第二种是wait/notify方法,第一种在前面代码中有解释,sleep里面的参数为多少毫秒,而第二种wait(),wait分为三类,第一类是无参数,需要靠notify唤醒,第二类为一个参数,多少之后自己被唤醒,参数单位为毫秒,第三类为俩个参数,也是自己被唤醒,第二个参数也是纳秒,因为第二类和第三类和sleep有点像,我们重点说一下第一类。

        

public class ThreadDemo24waitnotify {
    public static void main(String[] args) {
        Object locker=new Object();
        Object locker2=new Object();

        Thread t1=new Thread(()->{
            try {
                Thread.sleep(3000);
                System.out.println("wait之前");
                synchronized (locker){
                    locker.wait();
                }
                System.out.println("wait之后");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        Thread t2=new Thread(()->{
            Scanner scanner=new Scanner(System.in);
            System.out.println("输入任意内容");
            scanner.next();
            synchronized (locker){
                locker.notify();
            }
        });
        t1.start();
        t2.start();
    }
}

        打印结果如下:

        在调用wait方法的时候,线程进入阻塞状态,在写内容之后执行notify唤醒,就可以继续执行。

        注意:如果有多个线程使用同一个锁,那么notify只能唤醒其中一个,notifyall才能唤醒全部

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值