手记

Java线程和进程

进程和线程的关系:

  • 每一个进程对应一个JVM实例,多个线程共享JVM里的堆

  • JAVA采用单线程编程模型,程序会自动创建主线程

  • 主线程可以创建子线程,原则上要后于子线程完成执行

Thread中的Start和run的区别

  • 调用start()方法会创建一个新的子线程并启动

  • run()方法只是Thread的一个普通方法的调用

Thread和Runnable有什么关系

  • Thread实现了Runnable接口的类,使得run支持多线程

  • 因为类的单一继承原则,推荐多使用Runnable接口


如何实现处理线程的返回值

  • 主线程等待法,当线程多,代码多,不能精准控制

  • t.join(); 阻塞当前线程以等待子线程处理完毕

  • 通过Callable接口实现:通过FutureTask Or线程池获取


线程的状态:

新建(New):创建后尚未启动的线程的状态

运行(Runnable):包含Running和Ready

无限期等待(Waiting):不会被分配CPU执行时间,需要显示被唤醒

没有设置时间参数Object.wait()  Thread.join() LockSupport.park()

限期等待(time Waiting):在一定时间后会由系统自动唤醒

阻塞(Blocked):等待获取排他锁

结束(Terminated):已终止的线程


sleep和wait的区别:

基本的差别:

(1)sleep是Thread类的方法,wait是Object类中定义的方法

(2)sleep()方法可以在任何地方使用

(3)wait()方法只能在synchronized方法或synchronized块中使用

只有获取锁才能去释放锁

最主要的本质区别:

(1)Thread.sleep只会让出CPU,不会导致锁行为的改变

(2)Object.wait不仅让出CPU,还会释放以及占有的同步资源

notify和notifyAll的区别:

(1)notifyAll会让处于等待池的线程全部进入锁池去竞争获取锁的机会

(2)notify之后随机取一个

两个概念

锁池EntryList 等待池WaitSet

锁池的本质:

    假设线程A已经拥有了某个对象的锁,而其它线程B、C要调用这个对象的某个synchronized方法,由于B、C线程在进入对象的synchronized方法之前必须先获得该对象锁的拥有权,而恰好该对象的锁目前被线程A占用,此时B、C线程就会阻塞,进入一个地方去等待锁的释放,这个地方便是该对象的锁池

等待池:

    假设线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入到等待池中的线程不会去竞争该对象的锁。

二、 yield()方法

    当调用Thread.yield()函数时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽视这个暗示。(不会让出锁)


如何中断线程

调用interrupt(),通知线程应该中断了

(1)如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常

sleep、wait

(2)如果线程处于正常活动状态,那么会将该线程的中断标志设置为true。被设置中断标志的线程将会继续正常运行,不受影响

需要被调用的线程配合中断

(1)在正常运行任务时,经常检查本线程的中断标志,如果被设置了中断标志就自行停止线程。

(2)如果线程处于正常活动状态,那么会将线程的中断标志设置为true。被是指中断标志的现场将检修正常运行,不受影响








0人推荐
随时随地看视频
慕课网APP