美文网首页
Java基础-线程 (二)

Java基础-线程 (二)

作者: 森屿暖茶 | 来源:发表于2021-01-29 13:49 被阅读0次

    线程的6种状态(生命周期):

    1.NEW:创建一个线程对象new Thread(),没有调用start()方法,仅分配线程所需的资源。

    2.RUNNABLE:准备就绪 或 运行中。

    3.BLOCKED:表示线程阻塞于锁。场景:调用Thread.sleep()阻塞、等待IO操作或者某个锁、等待一定的触发条件。一次阻塞就将会进行一次上下文切换,而上下文切换是很耗费性能的(上下文切换3~5ms,执行一条命令0.6ns)。

    4.WAITING:进入该状态的线程需要等待其他线程做出一些特定动作,场景:线程可能因为调用了Object.wait()或Thread.join()。

    5.TIMED_WAITING:在指定等待时间后等待线程的线程状态,场景:可能因为调用Thread.sleep()或加上超时值来调用Object.wait()或Thread.join()

    6.TERMINATED:线程已运行完毕。它的run()方法已正常结束或通过抛出异常而结束。

    线程饥饿:指线程的优先级太低,总是拿不到执行权。

    死锁:在两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象

    发生场景:多使用者(M>=2),多被使用者(N>=2),且N<=M时才会发生这种情况。

    举个栗子:

    张三和李四在2个小黑屋。由于太黑了他们都想照亮房间,我们指定照亮房间的操作必须要持有打火机和蜡烛,才能点燃照亮。由于可能会发生这种情况。张三拿到了打火机,李四拿到了蜡烛。他们再拿另外一个必需品的时候总是拿不到,但是手里的资源又不放手。这样就产生了死锁。危害导致2个线程都挂在那不工作了,但是他们还一直处于运行状态。一般我们只能重启程序解决。

    总结:死锁一定是处于:请求保持,且不剥夺的条件下,处于环路等待的状态。

    解决:(下面描述的锁,其实就是被使用者)

    1.内部通过顺序比较,确定拿锁的顺序。通过协议避免

    2.采用尝试拿锁的顺序。(如A使用者在拿到N的时候尝试获取M,获取不到就释放N:(活锁)这种情况会导致互相谦让最终都拿不到或者执行多次才拿到的请,一般我们会使用线程休眠错开拿锁时间,来解决这个现象)

    ThreadLocal是什么?

    ThreadLocal字面意思就是线程的本地变量。可以理解他是线程私有的一个本地变量副本。主要作用是实现了变量的线程隔离。可以理解它存储这本线程的局部变量。

    值互不相影响

    为什么会这样,看一下源码:

    threaLocal.set()

    拿到当前线程的ThreadLocalMap,我们看一下Thread类和Thread类的getMap(t)方法。

    ThreaLocal类中的getMap() Thread类中

    所以map.set方法就是拿到当前线程的ThreadLocalMap,然后去set().

    ThreadLocalMap是一个数组 以threadLocal变量为键,value为值

    总结:ThreadLocal 就是线程的本地存储,他存储在线程内部的ThreadLocalMap数组中。可以看做参数的工作副本,起到线程隔离的作用。

    相关文章

      网友评论

          本文标题:Java基础-线程 (二)

          本文链接:https://www.haomeiwen.com/subject/dgdzgktx.html