zoukankan      html  css  js  c++  java
  • 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只是让当前线程暂停一下,让系统的线程调度器重新调度一次。

        

  • 相关阅读:
    Linux BFS简介
    汇编语言学习——第二章 寄存器(CPU工作原理)
    _WSAStartup@8,该符号在函数 _main 中被引用
    javascript中处理引号编码"
    tornado+ansible+twisted+mongodb操作和维护系统开发自己主动(一个)
    ORA-00600: internal error code, arguments: [4194], [53], [41], [], [], [], [], []
    【leetcode】Valid Palindrome
    开源 自由 java CMS
    创建分和生日比较数组
    有关动态多维数组的一个问题
  • 原文地址:https://www.cnblogs.com/UalBlog/p/10594815.html
Copyright © 2011-2022 走看看