Java多线程概念(一)

线程安全:

经过加锁保证数据的一致性.也就是说当一个线程访问某个数据时,经过加锁操做对数据进行保护,其它线程在加锁期间不能对其访问

线程封闭

当多个线程访问共享变量时,须要经过加锁来保证数据同步,增长了程序的复杂性. 避免数据同步的一种方式是不共享变量,好比使用局部变量和ThreadLocal

线程调度

系统为线程分配CUP使用权的过程
  • 协同式线程调度
线程的执行时间由线程本身控制,当本身执行完后,主动通知操做系统切换到另一个线程上执行. 好处是实现简单,线程对本身的操做是可知道的,没有什么线程同步问题.缺点是线程执行时间不可控,若是一个线程有问题,可能会一致阻塞在那里.
  • 抢占式线程调度
每一个线程的执行时间有操做系统分配,线程的切换不禁线程自己决定(Java中,Thread.yield()可让出执行时间,但没法获取执行时间)线程执行时间系统可控,也不会有一个线程致使进程阻塞.

java线程调度就是抢占式调度

能够经过设置线程的优先级让一些线程尽量的先执行多执行(Java一共有10个线程优先级从Thread.MIN_PRIORITY至Thread.MAX_PRIORITY),在两个线程同时处于ready时,优先级越高越容易被执行.但优先级并不靠谱,由于Java线程时经过映射到原生线程来实现的,因此线程调度仍是取决于操做系统.

状态转换

  • 新建(New)建立后还没有启动的线程
  • 运行(Runnable):Runnable包括操做系统中的Running和Ready. 处于此状态的线程有可能在运行,也有可能在等待CPU为它分配执行时间.线程建立后,其它线程调用了该线程的start方法,那么该线程就位于可运行线程池中,变得可运行,就差CPU分配执行时间,其它运行所须要的资源都已经得到.
  • 无限期等待(Waiting):该状态下的线程不会被分配CPU执行时间,要等待被其它线程进行显示唤醒. 如没有设置timeout的Object.wait()方法和Thread.join()方法,以及LockSupport.park()方法
  • 限时等待(Timed Waiting):该状态下的线程不会被分配CPU执行时间,只不过不须要被显示的唤醒,在必定时间后会被系统自动唤醒. 如Thread.sleep(),设置了timeout的Object.wait()和Thread.join(),LockSupport.parkNanos()以及LockSupport.parkUntil()方法
  • 阻塞(Blocked):线程被阻塞了,与等待的区别是:阻塞线程在等待一个排它锁.
阻塞状态是由于某种缘由放弃CPU使用权,暂时中止执行,直到线程进入就绪状态,才有机会转到运行状态.
  • 结束(Terminated):线程执行完了或者异常退出了run()方法,该线程结束生命周期

阻塞常见的三种状况

1.等待阻塞(无限期等待):运行的线程执行wait()方法,该线程会释放占用的资源,JVM会把该线程放入等待池.进入这个状态后,线程不会自动唤醒,必须依靠其它线程调用notify()或notifyAll()方法才能会被唤醒.java

2.同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被其它线程占用,则JVM会把该线程放入锁池.
3.其它阻塞(限时等待):运行的线程执行了join()或者sleep()方法,或者发起了I/O请求,JVM会把该线程置为阻塞状态,当sleep()状态超时,join()等待线程终止或者超时,I/O处理完成,该线程从新转入就绪状态.安全

相关文章
相关标签/搜索