线程理解

197 阅读4分钟
线程状态
1、创建线程
  • 继承Thread类并实现run()方法
  • 实现Runnable接口,并将实现了Runnable接口的实例放入new Thread(RunnableImpl)

注意 : 实现Runnable接口的类实例只是任务,而不是线程,线程是Thread

2、Thread使用
  • NEW (新建)
    一个尚未启动的线程处于这一状态。(A thread that has not yet started is in this state.)
  • RUNNABLE (可运行)
    一个正在 Java 虚拟机中执行的线程处于这一状态。(A thread executing in the Java virtual machine is in this state.)
  • BLOCKED (阻塞)
    一个正在阻塞等待一个监视器锁的线程处于这一状态。(A thread that is blocked waiting for a monitor lock is in this state.)
  • WAITING (等待)
    一个正在无限期等待另一个线程执行一个特别的动作的线程处于这一状态。(A thread that is waiting indefinitely for another thread to perform a particular action is in this state.)
  • TIMED_WAITING (计时等待)
    一个正在限时等待另一个线程执行一个动作的线程处于这一状态。(A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.)
  • TERMINATED (终止)
    一个已经退出的线程处于这一状态。(A thread that has exited is in this state.)
  • Thread类的使用 首字母大写的Thread代码静态方法,首字母小写thread实例方法 lock 代表锁对象
  • Thread.yield() 释放cpu、锁资源不释放 Running --> Ready 让当前线程释放cpu,该线程和其他线程的优先级相同,一起竞争cpu
  • Thread.sleep(n) 释放cpu、锁资源不释放 Running --> TIMED-WAITING -> Ready 让当前线程睡眠n毫秒。
  • thread.join() | thread.join(n) 线程A需要竞争线程B的锁资源 所以有可能是 BLOCKED | WAITING | TIMED_WAITING
    线程A执行体中,使用线程B调用join()方法,必须等待线程B执行完毕,需要注意的地方是join方法里面等待是调用wait()方法,也就是说线程A执行join()方法必须获取线程B实例作为锁才能执行join方法,查看源码join()是带有synchronized; 带时间的join,时间一到就直接,首先获取B线程对象锁,然后才能执行下面的流程,如果B线程实例锁被其他线程占用,A线程要继续等待直到B线程执行完成,然后A线程需要竞争锁资源,获取到锁资源之后再往下执行
  • lock.wait() | lock.wait(n) 释放cpu、释放锁资源 Running -> WAITING | TIMED_WAITING --> BLOCKED 首先wait()方法必须在synchronized代码块里面,让该线程 释放当前线程的cpu、锁资源等待其他线程调用notify()|notifyAll()|等待超时,线程进入锁资源竞争队列
  • lock.notify | lock.notifyAll() Running-->退出synchronized代码块-->释放锁资源 首先wait()方法必须在synchronized代码块里面,所以该线程必须先得到锁资源,通知其他线程等待结束,当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争。 为什么生产者消费者使用 notifyAll(),而不使用notify(),notify()随机通知一个线程,如果是生产者通知,有可能通知到了之前wait()的生产者,所以必须用notifyAll(),为什么用while(threhold),是因为使用了notifyAll()通知了所以的线程,有可能超过阀值。
  • thread.interrupt()
    给线程设置一个中断标志,线程仍会继续运行,如果线程中调用了 sleep() | wait() | join()等方法,不包括等待锁资源。
  • thread.isInterrupted() 获取线程终点标志中的值是否为中断
  • Thread.interrupted() 获取当前线程的中断标志,并且设置线程的中断标志为false
  • **总结一下 **

TIMED_WAITING 状态下的的线程,如果时间到了(只是不需要notify、unpark来通知),当前在锁范围内还需要重新获取锁资源才能执行