十一城

跬步千里,小流江海。

Home Linux ML Python Java Thoughts KmKg BookCan Links About

2018-01-16
java的多线程

• 分类: java • 标签:

神之双手,从不留痕。我们至今不知道他的存在,但他却操控着一些微妙的连锁反应,从而影响着这个世界的进程。

进程(ps)与线程(thread)

  • 进程:正在运行的程序,是系统进行资源分配的独立单位
  • 线程:进程的执行路径,调度和执行的单位,单个路径单线程,多个路径多线程

本质区别:每个进程拥有自己的一套变量,而线程只是共享数据。

多进程的意义:提高CPU的使用率

多线程的意义:提高应用程序的效率

线程

线程的五大状态

  • 新建状态:创建线程对象

  • 待运行:线程调用start()之后,有执行的资格,没有执行权

  • 运行:获得cpu的执行权(当加锁保证线程安全时会进入锁池等待获取锁,即同步阻塞)

  • 阻塞: ①等待阻塞:Object的wait()方法调用后, 进入等待队列,唤醒后进入锁池,获得锁后又回到待运行状态

    ​ ②同步阻塞:争抢cpu使用权,没抢到手,进入锁池等待获得锁

    ​ ③其他阻塞:如sleep()join(),时间结束后进入待运行状态

  • 死亡:run,main执行结束,或因异常退出

线程的两种调度模型

  • 分时调度模型:所有线程轮流使用CPU的使用全,平均分配每个线程占用cpu的时间
  • 抢占式调度模型(java采用):优先级最高为10,最低为1,多个抢占,一个运行

start()方法和run()方法的区别

  • run()方法仅仅是封装线程执行的代码,直接调用是普通方法
  • start()方法是启动线程,由java去调用run()方法

线程终止的两大原因

  • 当线程的run()执行方法体中最后一条语句后,并经由return语句返回时
  • 出现没有捕获的异常时,线程将终止

产生线程安全问题

  1. 是否是多线程环境
  2. 是否有共享数据
  3. 是否有多条语句操作共享数据

以上三个问题同时出现会出现线程安全问题。解决方案通常为把多个语句操作共享数据的代码给锁起来,让任意时刻只有一个线程执行即可。

线程间的协作

  • wait()
  • notify()
  • notifyAll()

wait()sleep()的区别

  • sleep()来自Thread类,wait()来自Object类
  • 调用sleep()方法的过程中,线程不会释放对象锁。而调用wait()方法线程会释放对象锁
  • sleep()睡眠后不出让系统资源,wait()让出系统资源其他线程可以占用CPU
  • sleep(milliseconds)需要指定一个睡眠时间,时间一到会自动唤醒

相同点

  1. 在多线程环境下调用可阻塞指定的秒数,并返回
  2. 两者都可以调用interrupt()方法打断线程的暂停状态

不同点

  1. 每个对象都有一个锁来控制同步访问,Stnchronizad关键字可以和对象的锁交互,来实现线程的同步。sleep()方法没有释放锁,而wait()释放了锁,使得其他线程可以使用同步控制块或者方法
  2. wait()notify()notifyAll()只能在同步方法或者同步控制块中使用,而sleep()可以在任何地方使用
  3. sleep()必须捕获异常,而wait(),notify,notifyAll不需要捕获异常
  4. sleep()是线程类Thread的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复
  5. wait()Object的方法,调用会放弃对象锁,进入等待队列,待调用notify唤醒指定的线程或者notifyAll唤醒所有线程,才会进入锁池,当获得对象锁,进入运行状态

参考

  1. http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
  2. http://www.cnblogs.com/way_testlife/archive/2011/04/16/2018312.html

dzzxjl

Home Linux ML Python Java Thoughts KmKg BookCan Links About