java中的多线程(二)


Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联。

线程创建

前面我们已经讲过了如何使用Thread 类创建多线程,下面我们来讲一下Thread创建多线程不同的几种的几种方法

Thread() 创建线程对象

Thread t1 = new Thread();                                                                                                          

Thread(Runnable target) 使用 Runnable 对象创建线程对象

Thread t2 = new Thread(new MyRunnable());

Thread(String name) 创建线程对象,并命名

Thread t3 = new Thread("这是我的名字");

Thread(Runnable target, String name) 使用 Runnable 对象创建线程对象,并命名

Thread t4 = new Thread(new MyRunnable(), "这是我的名字");

线程中断

之前我们已经看到了如何通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。这里我们还需要调用start方法来启动线程

start方法启动线程

package Thread;

public class ThreadDemo6 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (true) {
                System.out.println("hello t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"我的线程");
        t.start();
    }
}

在这里插入图片描述

使用自定义的变量来作为标志位.

package Thread;

public class ThreeDemo9 {
    public static boolean isQuit=false;
    public static void main(String[] args) {
        //boolean isQuit=false;变量捕获此处若被final修饰或未被final修饰未改变值则可以捕获
        Thread t=new Thread(()->{
            while (!isQuit){
                System.out.println("hello t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("t线程终止");
        });
        t.start();
        //在主线程上修改isQuin
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        isQuit=true;
    }
}

在这里插入图片描述

使用 Thread.interrupted() 或者 Thread.currentThread().isInterrupted() 代替自定义标志位.

package Thread;

public class ThreadDemo10 {
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            //currentThread是获取到当前线程案例
            //此处currentThread得到的对象就是t
            //isInterrupted就是t对象自带的一个标志
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("hello t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //此处interrupt会通过报错将阻塞状态sleep唤醒并同时将标志位清空变为false
                    break;
                }
            }
        });
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //把t内部的标志位给设置成true
        t.interrupt();
    }
}

在这里插入图片描述

thread 收到通知的方式有两种:

  1. 如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以InterruptedException 异常的形式通知,清除中断标志当出现InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法.
    可以选择忽略这个异常, 也可以跳出循环结束线程.
  2. 否则,只是内部的一个中断标志被设置,thread 可以通过
    Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志
    Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。

线程等待

我们编写一个简单的线程代码,让t线程和main线程同时运行此时我们会发现mian线程会优先打印t线程后打印,而实际上线程的运行是并发并行随机的,可能这次是mian线程先运行,但下次就不一定了

package Thread;

public class ThreadDemo11 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            System.out.println("hello t");
        });
        t.start();
        System.out.println("hello main");
    }
}

在这里插入图片描述

等待一个线程-join()

package Thread;
public class ThreadDemo11 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            System.out.println("hello t");
        });
        t.start();
        t.join();
        System.out.println("hello main");
    }
}

在这里插入图片描述
此时我们通过jion方法可以让t线程先运行再运行mian线程,而jion方法就是等待一个线程完成它的工作后,才能进行自己的下一步工作

线程休眠

因为线程的调度是不可控的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的

public static void sleep(long millis) throws InterruptedException 休眠当前线程 millis毫秒
public static void sleep(long millis, int nanos) throws InterruptedException 可以更高精度的休眠
其实休眠线程的方法,我们上面就有使用到的,为了可以清晰的看见线程的打印顺序

package Thread;

public class ThreadDemo11 {
     public static void main(String[] args) throws InterruptedException {
    System.out.println(System.currentTimeMillis());
     Thread.sleep(3 * 1000);
     System.out.println(System.currentTimeMillis());
  }

在这里插入图片描述
这里的 currentTimeMillis()方法是返回从1970年1月1日午夜(UTC)开始到当前时间的毫秒值而中间休眠了3000毫秒,再次打印就经历了3000毫秒再次打印

获取线程引用

public static Thread currentThread(); 返回当前线程对象的引用

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

在这里插入图片描述
通过 currentThread();我们就可以获取到线程状态 ,此时我们获取到的就是mian线程

getState()方法获取当前线程状态

public static void main (String[] args) {
            Thread t = new Thread(()->{
                System.out.println("hello Thread");
            });
            System.out.println(t.getState());
        }

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值