线程的创建

本文详细介绍了在Java中创建线程的三种方法:通过Thread类、Runnable接口和Callable接口,以及线程从新建到结束的整个生命周期状态,包括新建、就绪、运行、阻塞、等待和结束。

一:通过Thread类:
   继承Thread类的方法创建线程:
   1:定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体代表了线程需要完成的任务。
   2:创建Thread子类的实例,即创建了对象。
   3:调用线程对象的start()方法来创建并启动线程。

例如:

 /*
    *
     * @Author
     * @Description 线程方法体
     * @Date 14:19 2019-12-16
     * @Param []
     * @return void
     **/
   @Override
   public void run(){
       System.out.println("Hello Concurent World");
  }

    public static void main(String[] args) {
        System.out.println("----创建线程-------");
        SysController sysController = new SysController();
        System.out.println("-----启动线程------");
        sysController.start();

    }

结果:
在这里插入图片描述
二:通过Runnable接口:
   1:实现Runnable接口的实现类,并重写接口的run()方法,该run()方法的方法体就是线程执行体:
    2:创建Runnable实现类的实例,并以此实例作为Thread类构造函数创建Thread对象,该Thread对象才是真正的线程对象。
例如:

public class  SysController implements Runnable{
    /*
    *
     * @Author
     * @Description 线程方法体
     * @Date 14:19 2019-12-16
     * @Param []
     * @return void
     **/
   @Override
   public void run(){
       System.out.println("Hello Concurent World");
  }

    public static void main(String[] args) {
        System.out.println("----创建线程-------");
        SysController sysController = new SysController();
        Thread thread = new Thread(sysController);
        System.out.println("-----启动线程------");
        thread.start();

    }
}

结果:在这里插入图片描述
对于Runnable 接口源码:
在这里插入图片描述
run方法是无返回值的,没有参数,所以如果是多线程异步的情况,没有返回值没有办法区分哪个线程!!!!!
三:Callable接口(不常用):
    实现Callable接口:
   1:实现Callable接口的实现类,并实现Call()方法,该Call()方法将作为线程的执行体,且该Call()方法有返回值,再创建Callable实现类的实例。
   2:使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的Call()方法的返回值。
   3:使用FutureTask对象作为Thread对象的构造函数创建并启动新线程。
   4:使用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
例如:

public class  SysController{
    public static void main(String[] args) {
        FutureTask task = new FutureTask(()->{
            int count = 0;
            for (int i = 0;i <= 100;i++){
              count+=i;
            }
            return count;
        });
        //创建线程
        Thread thread = new Thread(task);
        //启动线程
        thread.start();
        try {
            //获取线程返回值
            System.out.println("1+2+3+4+5+6...."+task.get());
        }catch (InterruptedException e){
            e.printStackTrace();
        }catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

结果:
在这里插入图片描述
四:线程生命周期:
   1:新建
new 关键字创建线程对象时的状态。
例如:
SysController sysController = new SysController();
   2:就绪
通过线程对象的start()方法启动线程时对应的状态,此时线程并不一定马上能进入运行状态,线程的运行由操作系统的调度程序控制。
这里涉及到一个问题:
start()方法线程一定会开启吗?
答:如果当前Cpu有空闲,可以马上开启,但是如果Cpu没有空闲,则不会得到Cpu的时间片则不会开启。
   3:运行(是以时间片来执行的,把程序分为好几段,这段时间执行这个时间段的代码):
获取Cpu的执行权,线程正在执行需要执行的代码。
执行的是:

 @Override
   public void run(){
       System.out.println("Hello Concurent World");
  }

或者

 @Override
    public Object call() throws Exception {
        return null;
    }

   4:阻塞
Blocked称为阻塞状态,或者说线程已经挂起,原因是它在等待一个”锁“。也就是说run()和call()不能执行。
线程阻塞:
(1):线程在等待一个锁,当尝试进入一个Synchronized语句块/方法块时,锁已经被其他线程占有,就会被阻塞,直到另一个线程走完临界区或者发生了相应锁对象的wait()操作后,它才有机会去争夺进入临界区的权利
(2):处于阻塞状态的线程,即使对其调用thread.interrupt()也无法改变其阻塞状态,因为interrupt()方法只是设置线程的中断状态,不能唤醒处于阻塞状态的线程。
(3):ReentrantLock.lock()操作后进入的是Waiting状态,其内部调用的是LockSupport.park()方法。
   5:等待
分为:有限期等待和无限期等待。

   无限期等待有这样几种情况
    处于这种状态的线程不会被分配CPU执行时间,它们要等待被其他线程唤醒;
    没有设置timeout参数的Object.wait();
    没有设置timeout参数的Thread.join();
   LockSupport.park()。

   有限期等待有这样几种情况
   处于这种状态的线程也不会被分配CPU执行时间,不过无需等待被其它线程显示的唤醒
   Thread.sleep()方法;
   设置了timeout参数的Object.wait();
   设置了timeout参数的Thread.join();
   LockSupport.parkNanos()方法;
   LockSupport.parkUntill()方法;

   有这样一个问题:
   线程阻塞和线程等待区别
   "阻塞"状态是等待着获取到一个排他锁,进入"阻塞"状态都是被动的,离开"阻塞"状态是因为其他线程释放了锁,不阻塞了;
   "等待"状态是在的等待一段时间或者唤醒动作的发生,进入"等待"状态是主动的。

   6:结束
   run()方法和call()方法执行完成,线程正常结束;
   线程抛出一个未捕获的Exception 或 Error;
   直接调用线程的stop()方法来结束线程。

关系图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值