zoukankan      html  css  js  c++  java
  • 线程基本知识

    概念:线程就是轻量级的进程,是程序执行的最小单位。

    tip1:线程的五种状态:
    1、新建   
      新建了一个线程
    2、可运行 
      线程的start()方法被调用,该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权
    3、运行状态
      获取CPU时间片,执行代码块
    4、阻塞
      (一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
      (二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
      (三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
    5、死亡
      死亡(DEAD):线程run()、main() 方法执行结束


    tip2:线程的创建

    继承Thread和实现Runnable接口【默认的Thread.run()就是调用内部的Runnable接口】

    tip3:线程的关闭

    Thread的stop()方法

    不推荐,原因是stop方法在结束线程时,会立刻是否这个线程所持有的锁。如果写线程写到一半,强行终止,对象就会被写坏,同时,由于锁已经释放,另一个等待该锁的读线程就读到了这个对象。

    扩展知识:

    一、JDK、JRE和JVM三者之间关系:  

    1、所有的JAVA程序都会被编译成class文件,由虚拟机JVM和操作系统交互
    2、JVM需要调用解释所需要的类库lib才可以执行class文件,JVM+lib=JRE即JAVA运行环境
    3、JDK主要用于程序开发,最主要是编译器,包含了JRE,JAVA工具类和JAVA基础类库

    二、怎么实现线程

    实现Runnable接口或者继承Thread类来实现,当你打算多重继承时,优先选择实现Runnable

    三、Thread.start()与Thread.run()有什么区别

    调用start()后,线程会被放到等待队列,等待CPU调度。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体

    四、为什么需要run()和start()方法,我们可以只用run()方法来完成任务吗

    start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程。run()只是一个线程里的一个函数,和多线程无关

     1 public synchronized void start() {
     2         if (threadStatus != 0)
     3             throw new IllegalThreadStateException();
     4         group.add(this);
     5 
     6         boolean started = false;
     7         try {
     8             start0();
     9             //private native void start0(),使用native修饰,Thread类要调用本地方法,要向JVM注册,这个方法调用了run方法
    10             started = true;
    11         } finally {
    12             try {
    13                 if (!started) {
    14                     group.threadStartFailed(this);
    15                 }
    16             } catch (Throwable ignore) {
    17             }
    18         }
    19     }

    五、什么是ThreadLocal类,怎么使用它

    通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改

    六、什么时候抛出InvalidMonitorStateException异常,为什么

    调用wait()/notify()/notifyAll()中的任何一个方法时,如果当前线程没有获得该对象 的锁,那么就会抛出IllegalMonitorStateException的异常

    七、多线程中sleep、supend和wait区别

    共同点:都会阻塞当前线程

    不同点:

      1、sleep不会交出任何已获得的对象锁,是Thread类的方法,是线程用来控制自身流程的,调用此方法要捕捉InterruptedException异常

      2、wait会交出调用wait对象的对象锁。是Object类中定义的方法,用来线程间的通信,而且wait存在notify方法来唤醒调用wait的线程。

      3、suspend,使线程进入停滞状态,除非收到resume消息,否则该线程不会变回可执行状态

    八、多线程中wait/notify区别

    1、wait() 与 notify/notifyAll 方法必须在同步代码块中使用

      wait() 与 notify/notifyAll() 是Object类的方法,在执行两个方法时,要先通过synchronized['sɪŋkrənaɪzd]获得锁

    2、notify/notifyAll()执行后,并不立即释放锁,而是要等到执行完临界区中代码后,再释放

    3、多线程中测试某个条件的变化用 if 还是用 while?

    List中没有数据了,再还是有线程去执行删除数据的操作。因此,需要用while循环来判断条件的变化,而不是用if

    九、在静态方法上使用同步时会发生什么事

    Synchronized修饰静态方法,实际上是对该类对象加锁,俗称“类锁”

    答案:http://blog.csdn.net/u010842515/article/details/65443084

    十、Thread的join方法

    1、Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行

    2、join方法必须在线程start方法调用之后调用才有意义

    3、join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的

    十一、死锁

    形成原因:循环等待,多线程申请多资源,形成了循环等待

    1、互斥:进程在某一时间内独占资源;
    2、持有:一个进程因请求资源而阻塞时,对已获得的资源保持不放;
    3、不可剥夺:进程已获得资源,在末使用完之前,不能强行剥夺;
    4、环形等待:若干进程之间形成一种头尾相接的循环等待资源关系;

    解决方法:

    1、针对2和3,引入事务机制,将所有上锁操作均作为事务对待,一旦开始上锁,即确保全部操作均可回退,同时通过锁管理器检测死锁,并剥夺资源

    2、针对4,约定上锁的顺序必须一致

    3、在尝试获取锁的时候加一个超时时间

    4、死锁检测机制

    每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。
    当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。

    知识补充:

    一、Runnable接口和Callable接口的区别

    1、两者最大的不同点是:实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果;
    2、Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛;

    注意点:
    Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果。

    二、Volatile关键字的作用

    使用volatile关键字修饰的变量,保证了其在多线程之间的可见性,即每次读取到volatile变量,一定是最新的数据

    博客园:http://www.cnblogs.com/zhuziyu/
    Copyright ©2018 不是植物
    【转载文章务必保留出处和署名,谢谢!】
  • 相关阅读:
    Linux tcpdump命令详解
    移动开发网站收集
    Struts+2权威指南基于WebWork核心的MVC开发源码下载
    Eclipse+php插件+Xdebug搭建PHP完美开发/调试环境指南
    java相对目录和绝对目录解析
    python学习网站搜集
    window下开发iphone程序环境搭建iphone tool chain
    Windows下编译objectiveC
    java class路径获取
    完全优化MySQL数据库性能的八个方法
  • 原文地址:https://www.cnblogs.com/zhuziyu/p/8548554.html
Copyright © 2011-2022 走看看