课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
大家在学习java编程语言的过程中,对于线程的学习应该是非常重要的一项学习任务了,今天,我们就一起来了解一下,在进行线程处理过程中都有哪些操作方式。希望通过对本文的阅读,能够提高大家对线程处理的技术能力。
终止线程(stop)
不推荐使用Thread.stop(), 他会释放所有的monitor, 导致数据不一致.
假设有一条数据库记录, 有两个字段ID, Name.
为了保持同一条记录ID, Name一致, 会在读写该对象的时候加锁.
线程A获取到锁, 开始写操作, 写完ID = 1, 还没写Name, 被强制stop了, 释放掉了锁.
线程B拿到锁, 读取对象, 以为是线程安全的, 实际上数据是错的, 只有ID有值, Name为null.
中断线程(interrupt)
可以通过调用thread.interrupt()对线程进行中断操作.
当线程收到interrupt信号后, 可能会有两种场景:
线程处于运行状态 : 将isinterrupt置为true
线程处于阻塞状态 : 抛出InterruptedException, isinterrupt为false.
挂起(suspend) 和 继续执行(resume)
@Deprecated不推荐使用, 原因是如果在多线程环境中, 假设多个线程调用线程A的suspend和resume.
如果线程B先调用了threadA.suspend(), 线程C再调用threadA.resume(), 则没问题.
如果线程B先调用了threadA.resume(), 线程C再调用threadA.suspend(), 这个时候将导致线程A处于冻结状态, 其持有的锁无法释放.
等待线程结束(join) 和 谦让(yield)
yield
可以让当前线程暂停一下, 类似于sleep, 但是他不会阻塞该线程, 只是从运行状态切换为就绪状态.
当yeild执行后, 优先级大于等于当前线程优先级的所有线程都会有竞争CPU执行的机会, 他自身也会参与竞争.
join
该操作会使得线程执行存在等待, 如果A线程调用B线程的join操作, 则A会等待B执行完成后, 才会继续往下执行.
线程B执行完毕后, 系统会调用notifyAll()来通知所有等待线程.
join也可以指定时间参数, 等待N秒后, 无论目标线程是否完成, 当前线程都会继续往下执行.
sleep
sleep相对容易理解, 他会使得当前Thread进入阻塞状态, 同时不释放该线程占用的锁.
守护线程
在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程就可以理解为守护线程
当一个Java应用内,只有守护线程时,Java虚拟机就会自然退出
在一个大型系统中, 应当在new Thread的时候给他加上是否为守护线程, 以及线程名称.
防止系统退出的时候, 出现一堆Thread未关闭阻塞退出.
线程优先级
高优先级的线程更容易在竞争中获胜, 但并不是绝对的.
线程的同步操作
synchronized
指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁
直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁
直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁
Object.wait 和 Object.notify notifyAll
三个方法都是Object对象的方法, 需要在synchronized语句块内使用.
wait
使当前线程暂停执行并释放对象锁标示, 让其他线程可以进入synchronized数据块, 当前线程被放入对象等待池中
notify
从对象的等待池中移走一个任意的线程并放到锁标志等待池中, 只有锁标志等待池中线程能够获取锁标志;
如果锁标志等待池中没有线程,则notify()不起作用
notifyAll
从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中
作者:大道方圆
来源:博客园
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。