Thread类的基本用法

一、创建线程

1)继承Thead类:对于当前线程的引用,可以直接使用this引用

//1.继承Thread,创建线程类
class MyThread extends Thread{
    //这里的run方法重写了Thread中的方法
    public void run(){
       System.out.println(" 线程运行 ");
    }
}
public class Main{
  public static void main(String[] args){
   //2.创建MyThread 类的实例
   MyThead t = new MyThread();
   //3.调start来启用线程
   t.start();
  }
}

2)实现Runnable接口:此时的this表示的是对与MyRunnable的引用,当前线程对象要用Thread.currentThread()

class MyRunnable implements Runnable{
     public void run(){
        System.out.println("线程运行");
     }
}
public class Main{
    public static void main(String[] args){
       Thread t = new Thread(new MyRunnable());
          t.start();
     }
}   

3) 匿名内部类创建Thread子类对象

public class Main{
   public static void main(String[] args){
      Thread t = new Thread(){
        public void run(){
          System.out.println("线程运行");
        }
      };
   } 
}

4)匿名内部类创建Runnable子类对象

public class Main{
   public static void main(String[] args){
     Thread t = new Thread(new Runnable(){
       public void run(){
        System.out.println("线程运行");
       }
     });
   }
}

5)lambda 表达式创建Runnable子类对象

Thread t = new Thread(() -> {
      System.out.println("线程运行");
});

二、线程中断

线程中断并不是说让线程立即停止,而是通知线程该停止了,是否真正意义上的停止还看线程中的代码的写法。

线程中断的常见的两种方式:1.通过共享的标记沟通 2.调用interrupt()方法来通知

//通过共享的标记沟通  对于flag值的改变来通知线程的中断
public class ThreadDemo{
     public static boolean flag = false;
     public static void main(String[] args){
         Thread t = new Thread(() -> {
           while(flag){
              System.out.println("hello thread");
              try{
                 Thread.sleep(1000);
               }catch(InterruptedException e){
                 e.printStackTrace;
               }
           }
         };
            t.start();
        // 在主线程里就可以随时通过 flag 变量的取值来操作 t 线程是否结束.
        flag = false;
     }
}
public class ThreadDemo{
    public static void main(String[] args) throws InterruptedExcetion{
        Thread t = new Thread(() -> {
          while(!Thread.currentThread().isInterrupted()){
             System.out.println("hello Thread");
             try{
                 Thread.sleep(1000);
             }catch(InterruptedException e){
                e.printStackTrace();   
                   //当这里的线程没有主动break时,线程在抛出异常后会继续运行循环
             }
           }
         });
         t.start();
         Thread.sleep(3000);
         t.interrupt();
    }
}

若是线程在sleep中休眠,此时调用interrupt会把线程唤醒,从而会触发sleep中的异常,提前将线程返回。

此时interrupt相当于做了两件事情:

一是把线程内部的标志位(boolean)给设置成true

二是若线程处于sleep,触发异常,把sleep唤醒,同时还会把刚刚设置成true的标志位设置回false

以上两点形成的运行结果如下:

 调用interrupt只是通知线程该终止,是否要真的终止,还得看线程内的代码

public class ThreadDemo{
    public static void main(String[] args) throws InterruptedExcetion{
        Thread t = new Thread(() -> {
          while(!Thread.currentThread().isInterrupted()){
             System.out.println("hello Thread");
             try{
                 Thread.sleep(1000);
             }catch(InterruptedException e){
                e.printStackTrace();   
                    break;   //线程响应请求,立刻终止
             }
           }
         });
         t.start();
         Thread.sleep(3000);
         t.interrupt();
    }
}

运行结果如下:

 

public class Main{
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
      //稍后进行终止,以下可加入其他代码,以便在终止前有其他任务请求
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                   break;
                }
            }
        });
        t.start();
        Thread.sleep(3000);

        t.interrupt();
    }

三、线程等待 

线程调度是抢占式执行,是一个随机调度的过程,但往往随机是不可靠的,有的时候就需要等待一个线程完成他的工作后才能进行下一步工作,此时就需要线程等待join(),来控制两个线程之间的结束顺序。

public class ThreadDemo{
      public static void main(String[] args){
         Thread t = new Thread(() -> {
           System.out.println("hello Thread");
           try{
               Thread.sleep(1000);
           }catch(InterruptedException e){
            e.printStackTrace();
           }
         });
       t.start;
       try{
            Thread.sleep(5000);
       }catch(InterruptedExcetion e){
        e.printStackTrace();
       }
       System.out.println("join之前");
       try{
            t.join();
       }catch(InterruptedExcetion e){
        e.printStackTrace();
       }
      System.out.println("join之后");
     }
}

注:当线程执行到join的时候就会阻塞,进入阻塞队列,知道Thread线程执行结束,主线程main才会进入就绪队列,才可以被操作系统内核调度

四、线程休眠

线程休眠会由就绪队列进入阻塞队列。当指定的休眠时间结束,线程就可以由阻塞到就绪队列中,从而能够被调度,实际的休眠时间会大于等于我们设定的时间,以毫秒为单位,方法为sleep().

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值