Java并发编程 - 基础

@Author 何昊东
@Date 2017-02-19 14:25:30

线程优先级

设置线程优先级时, 针对频繁阻塞(休眠或I/O操作)的线程需要设置较高优先级, 而偏重计算(需要较多CPU时间或者偏运算)的线程则设置较低的优先级, 确保处理器不会被独占

Thread.yield() 
/* 使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,
也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。*/
Thread.join()
/* 如果一个线程A执行了thread.join()语句, 其含义是: 当前线程A等待thread线程终止后, 才从thread.join()返回, 超时版本的join 设置了超时时间 强制返回, 对于访问比较重要的资源的线程, 都应设置超时时间. */
Thread.wait() wait(long ms) wait(long , int) 
/*调用该方法的线程进入WAITING状态, 只有等待另外线程的通知或被中断才会返回, 需要注意, 调用wait()方法后, 会释放对象的锁 
  可以设置超时时间, 到时即使没有通知 也会返回 */
Thread.notify(thread t)
/* 通知一个在对象上等待的线程, 使其从wait()方法返回, 而返回的前提是该线程获取到了对象的锁 */
Thread.notifyAll()
/* 通知所有在改对象上等待的线程 */


*suspend() 和 stop() 方法被弃用的原因是: 调用方法后, 线程不会释放已经占有的资源(比如锁), 而是占有着资源进入睡眠状态, 很容易导致死锁问题. *

** wait(), notify(), notifyAll() 注意事项 **

  1. 需要先对调用对象加锁
  2. 调用wait() 后, 线程状态由 RUNNING 变为 WAITING, 并将当前线程放置到对象的等待队列
  3. notify() 或 notifyAll() 方法调用后, 等待线程依旧不会从wait() 方法返回, 必须要等到使用 notify(), notifyAll() 的线程释放锁之后, 等待线程才有机会从wait()返回
  4. notify() 方法将等待队列中的一个等待线程从等待队列中移到同步队列中, notifyAll() 方法则是将等待队列中所有的线程全部移动到同步队列, 被移动的线程状态由 WAITING 变为 BLOCKED.
  5. 从wait() 方法返回的前提是获得了调用对象的锁

线程的状态

P89


Java并发编程 - 基础_第1张图片
状态名称 说明
NEW 初始状态, 线程被构建, 但是还没有调用start()方法
RUNNABLE 运行状态, Java线程将操作系统中的就绪和运行两种状态笼统第称作"运行中"
BLOCKED 阻塞状态, 表示线程阻塞于锁
WAITING 等待状态, 表示线程进入等待状态, 进入改状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断)
TIME_WAITING 超时等待状态, 该状态不同于WAITING, 它是可以超时后自动返回的
TERMINATED 终止状态, 表示当前线程已执行完毕

阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态, 但是阻塞在java.concurrent 包中Lock接口的线程却是等待状态, 因为java.concurrent 包中Lock接口对于阻塞实现的效果均使用了LockSupport类中的相关方法

Daemon 守护线程

当一个Java虚拟机中不存在非Daemon线程的时候, Java虚拟机将会退出.
Daemon属性需要在启动线程之前设置, 不能在启动线程之后设置
在构建Daemon线程时, 不能依靠finally块中的内容来确保执行关闭或清理资源的逻辑

对象, 监视器, 同步队列和执行线程之间的关系

图见 p98
任意对象对Object(Object 由 synchronized 保护)的访问, 首先要获取Object的监视器. 如果获取失败, 线程进入同步队列, 线程变为BLOCKED. 当访问Object的前驱(获得了锁的线程)释放了锁, 则该释放操作唤醒阻塞在同步队列中的线程, 使其重新尝试对监视器的获取.

等待/通知 机制

WaitNotify.java , 详见p101, 核心是 wait(), notify(), notifyAll(), 经典范式: 加锁, 循环, 处理逻辑 三个步骤

管道输入/输出流

主要用于线程之间的数据传输, 而传输的媒介为内存. connect()方法连接输出/输入流, 分属两个线程
` PipedOutPutStream, PipedInputStream 面向字节, PipedWriter, PipedReader 面向字符

interrupt() 方法 和 InterruptException

详见这篇文章
Thread.interrupt()方法不会中断一个正在运行的线程。它的作用是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。
interrupt方法并不是强制终止线程,它只能设置线程的interrupted状态

你可能感兴趣的:(Java并发编程 - 基础)