第一章 Java多线程技能
这一章呢,作者没有写到核心知识,知识简单说明一下线程概念,多线程实现方式(继承Thread,实现Runnable)、共享数据的不安全性、停止线程、线程的优先级
一些方法的使用如下:
- currentThread() 返回当前代码被哪个线程调用的信息。
- isAlive()判断当前线程是否处于活跃状态。
- sleep()指定好描述让当前执行线程休眠。(不会放弃锁)
- getId()取得线程唯一标识。
- stop()强制停止,不推荐使用。
- interrupt()停止线程,不能立刻停止线程,是给当前线程打一个停止标记。
- interrupted() 检测当前线程是否已经中断,具有清除状态功能。
- isInterrupted() 检测线程是否已经中断。
- suspend() 暂停线程
- resume() 恢复线程
- yield()放弃当前CPU资源,让给其他任务。
- serPriority() 方法设置优先级,1~10个等级。
第二章 对象及变量的并发访问
第二章作者主要是对并发访问进行描述,对synchronized关键的使用准备了大量的用例,也验证了使用synchronize时的各种注意事项。
知识点梳理:
- 方法内变量线程安全,实例变量非线程安全。
- 使用synchronize关键字,对不同对象使用,会产生多个锁。
- 脏读就是读取实例变量时此值已经被其他线程更改过。(表里不一)
- synchronize(this)锁定的是当前对象
- synchronize锁重入,当前使用synchronize时,当一个线程得到某一个对象锁后,再次请求此对象锁可以再次得到锁。在一个synchronize方法的内部调用本类的其他synchronize方法时,可以直接得到锁。可重入锁支持在父子类继承的环境中。
- 同步不具有继承性,synchronize修饰的方法,继承后重写不具备synchronize特性。
- String加油常量池缓存,一般不作为synchronize的锁对象。
- 多线程的死锁,互相等待对方。
- volatile关键字 保证线程可见性且提供了一定的有序性,但是无法保证原子性。在JVM底层volatile是采用“内存屏障”来实现的。
第三章 线程间通信
多线程之间的通信,主要通过等待/通知机制实现。方法wait()使当前线程等待(释放锁),notify()方法用于唤醒某一个线程,执行完notify()方法后,不会马上释放该对象锁,notifyAll() 用于唤醒全部线程。
知识点梳理:
- 当线程呈wait()状态时,调用线程对象的interrupt()方法会出现InterruptedException异常。
- wait(long)等待某一时间是否有线程对锁进行唤醒,如果超过时间自动唤醒。
- 在经典的生产者-消费者中,使用while()替代if进行条件判断,因为wait()方法被唤醒后,是从wait()后代码继续执行,不是重新执行。
- 通过管道可以进行线程间通信:字节流。提供四个类在线程间通信。PipedInputStream,pipedOutputStream,PipedReader与PipedWrider.
- join() 方法,可以等待线程执行完再执行(等待线程销毁)。
- 方法join(long)内部使用wait(long)来实现,join(long)具有释放锁的特点。
- ThreadLocal使每个线程绑定自己的值。
第四章 Lock的使用
ReentrantLock的使用,相比于synchronize关键的使用显得更加的灵活,并且加上了更多更强大的功能。调用ReentrantLock独享的lock()方法获取锁,调用unlock()方法释放锁。
使用Condition实现等待通知
ReentrantLock实现等待/通知需要借助Condition对象,可以实现多路通知,在一个Lock对象里面创建多个Condition对象,注册对象可以注册在指定的Condition中,选择性的对线程通知,调度线程更灵活。
在notify/notifyAll方法进行通知,被通告的线程由JVM随机选择,但是使用ReentrantLock结合Condition可以实现选择性通知。
synchronize就相当于整个Lock对象中只有一个单一的Condition对象。
公平锁与非公平锁
锁Lock分为“公平锁”与“非公平锁”,意味着线程获取锁的顺序是否根据线程的加载顺序来分配。
可以通过ReentrantLock lock = new ReentrantLock(true) 创建公平锁,ReentrantLock默认创建的是非公平锁
知识点梳理:
- Object类中的wait() 相当于Condition中的await()方法
- Object类中的notify() 相当于Condition中的signal()方法
- Object类中的notifyAll() 相当于Condition中的signalAll()方法
- 可以通过ReentrantLock lock = new ReentrantLock(true) 创建公平锁
- int getHoldCount() 查询当前线程保持此锁的各式个数。
- int getQueueLength() 返回正在等待获取此锁定的线程估计数
- int getWaitQueueLength(Condition condition) 返回等待与此锁相关condition的线程估计数
- boolean hasQueuedThread(Thread thread) 查询指定的线程是否正在等待此锁。
- boolean hasQueuedThreads() 查询是否有线程正在等待此锁。
- boolean hasWauters(Condition condition)查询是否有线程正在等待与此锁有关的condition。
- boolean isFait() 是否公平锁
- boolean isHeldByCurrentThread()查询当前线程是否保存此锁
- boolean isLocked() 查询此锁是否有任意线程保持。
- void lockInterruptibly() 如果当前线程未被中断,获取此锁。
- boolean tryLock() 仅在调用时锁定未被另一个线程保持的情况下,才获取此锁。
- ReentrantRadWriteLock类,是一种读写锁。有两个锁,一个是读相关锁,称为共享锁;另一个是写相关锁,也叫排它锁。多个读锁不互斥,读写互斥,写写互斥。
收获不多,总结有限,代码偏多,适用入门,过度即可。
深入学习建议阅读《Java并发编程实战》