java多线程

创建线程的三种方式:

 一、继承Thread类创建线程类

  1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程需要完成的任务。

  2)创建Thread子类的实例,即创建线程对象。

  3)调用创建线程的start()方法启动该线程。

 注:Thread.currentThread():currentThread()是Thread类的静态方法,该方法总是返回当前正在执行的线程对象。

 二、实现Runnable接口创建线程类

  1)定义Runnable接口的是实现类,并重写该接口的run方法。

  2)创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真的线程对象。

    SecondThread st = new SecondThread();

    new Thread(st);

  3)调用线程对象的start()方法。  

 三、 使用Callable和Future创建线程

  1)创建Callable接口实现类,并实现call方法,该call方法作为线程执行体,且该call方法具有返回值。

  2)创建Callable实现类的实例,使用FutureTask类来包装Callable 对象,该FutureTask对象封装了该Callable对象的call方法返回值。

  3)使用FutureTask对象作为Thread对象的target创建并启动新线程。

  4)调用FutureTask对象的get方法来获得子线程执行结束后的返回值。

创建线程的三种方式对比

  通过实现Runnable与Callable接口实现多线程基本相同,只是Callable接口里定义的方法具有返回值,可以声明抛出异常而已。

  其与继承Thread类的方式主要有一下区别:

  1)线程只是实现了Runnable与Callable接口,还可以实现其他的类。

  2)在后者方式下,多个线程共享一个target对象,所以非常适合多个相同线程来处理同一份资源。

  3)使用继承Thread类来获取线程对象直接使用this即可获得当前线程,而前者需要调用Thread.currentThread方法。  

线程的生命周期

  新建,就绪,运行,阻塞,死亡。

一、新建(NEW),就绪(Runnable)

  当程序使用new关键字创建了一个线程后,该线程就处于新建状态,此时它和其他java对象一样,仅仅由java虚拟机分配内存,并初始化其成员变量的值。

  当线程调用了start方法之后,该线程就处于就绪状态,java虚拟机会为其创建方法调用栈和程序计数器,处于这个状态的线程并没有开始运行,只是表示可以开始运行了,至于何时开始运行,取决于JVM里线程调度器的调度。

二、运行(RUNNING)阻塞(Blocked)

  如果处于就绪状态的线程获得了cpu,开始执行run方法的执行体,则线程处于运行状态。

  当一个线程运行后,它不可能一直处于运行状态,线程在运行过程中需要被中断,目的是使其他线程获得执行机会。

  当发生如下情况,线程进入阻塞状态:

  1)线程调用sleep()方法主动放弃所占用的处理器资源。

  2)线程调用了一个阻塞式IO方法,在该方法返回之前,该线程被阻塞。

  3)线程试图获得一个同步监视器,但该同步监视器被其他线程所持有。

  4)线程等待某个通知notify

  5)程序调用了线程的suspend方法将该线程挂起(容易造成死锁)

  当发生如下情况,线程由阻塞转为就绪

  1)调用sleep方法经过了指定时间。  

  2)线程调用的阻塞式IO方法得到返回

  3)线程成功获得所请求的同步监视器

  4)线程正在等待某个通知时,其他线程发出了通知。

  5)处于挂起状态的线程调用了resume恢复方法

三、线程死亡(DEAD)

  线程会以如下三种方式结束,结束后就处于死亡状态。

  1)run或call方法执行完成,线程正常结束。

  2)线程抛出一个未捕获的Exception或Error。

  3)直接调用该线程的stop方法来结束该线程(容易死锁)。

  为了测试线程是否死亡,可以调用对象的isAlive方法,当线程处于就绪,运行,阻塞3种状态时,该方法返回true.。

控制线程

  一、join线程

  Thread提供了一个线程等待另一个线程完成的方法--join方法。当在某个线程中调用其他线程的join方法,调用线程会被阻塞,直到被join方法加入的join线程执行完为止。

  二、守护线程

  有一种线程,在后台运行,它的任务是为其他线程提供服务,这种线程称为后台线程(Daemon Thread),又称为精灵线程或守护线程。Jvm垃圾回收线程就是典型的后台线程。

  后台线程的特征:如果所有的前台线程都死亡,后台线程会自动死亡。

  调用Thread对象的setDaemon(true)方法(必须在start方法之前调用),可以将指定线程设置成后台线程。Thread还提供一个isDaemon方法,判断一个线程是否是后台线程。

  三、线程让步yield

  它是Thread类提供的一个静态方法,它也可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转化为就绪状态,yield只是让当前线程暂停一下,让系统的线程调度器重新调度一次。

    

原文地址:https://www.cnblogs.com/UalBlog/p/10594815.html