博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发基础笔记-(线程基础)
阅读量:6473 次
发布时间:2019-06-23

本文共 3479 字,大约阅读时间需要 11 分钟。

目录


  1. 线程基础
  2. 同步及实现
  3. 阻塞队列
  4. 线程安全集合
  5. Callable与Future
  6. 线程池-执行器
  7. 同步器-同步队列

线程 在较低层次扩展了 多任务 的概念

线程与进程的本质区别 每个进程有一套自己的变量, 而线程共享数据(线程间通信更有效, 容易)

创建

// 函数式接口 Runnable 实例Runnable r = () -> { /* task code */ };// 由 Runnable创建 Thread 对象Thread t = new Thread(r);// 启动该线程// t.run()只是调用run方法,不会启动新线程t.start();复制代码

中断线程

线程终止情况

  1. run方法执行结束, 并由return返回时
  2. 出现方法中没有捕获的异常时
  3. 早期版本中可以调用stop(), 后弃用

没有可以强制线程终止的方法 可以通过 interrupt() 请求终止线程

每个线程都有 中断状态 的boolean标志, 线程调用实例方法interrupt()将该标志置位(true), 应当时不时检测线程是否被置位

// Thread.currentThread()获取当前线程, isInterrupted()是否中断while(!Thread.currentThread().isInterrupted() /*&& more work to do*/){    // do more work}复制代码

线程被阻塞时, 调用interrupt(), 阻塞调用被InterruptedException中断, 且线程中断状态被重置(false), 因此, 此时检测中断状态isInterrupted()也就没有意义

方法
Thread.interrupted()清除中断状态(即: 重置为false)
中断一个线程是引起它的注意, 被中断的线程可以决定如何响应中断 如: 处理完异常之后继续执行
finally..., 不过普遍的是做为终止请求

注意

不要不处理InterruptedException

// 错误示范void testTask(){    ...    try{Thread.sleep(delay);}    catch(IntrrrputedException e){}    ...}// 正确方式1void testTask1(){    ...    try{Thread.sleep(delay);}    // 中断状态置位, 以便调用者检测    catch(InterruptedException e){ Thread.currentThread().interrupt(); }    ...}// 正确方式2// 抛出以便调用者捕获void testTask1() throws InterruptedException{    ...    Thread.sleep(delay);    ...}复制代码

线程状态

6种状态(t.getState()获取当前状态):

  • New(新创建)

    使用new创建线程时, 此时并未开始运行其中的代码

  • Runanble(可运行)

    调用start()进入该状态, 该状态的线程 可能在运行 也可能 没有运行, 线程开始运行未必始终运行, 运行中断是提供给其他线程运行机会,

    • 抢占式调度在线程时间片用完时剥夺运行权并根据优先级选择另一个线程
    • 协作式调度(手机), 调用yield方法(从运行中到就绪) 或被阻塞或等待时, 线程失去控制权
  • Blocked(被阻塞)

    该状态下不活动不运行代码并消耗最少资源, 直到被重新激活

    • 试图获得一个内部对象锁(非JUC库中的锁), 而该锁被其他线程持有, 进入阻塞状态. 当所有其他线程释放该锁, 且调度器允许该线程持有此锁, 进入可运行状态.
  • Waiting(等待)

    与阻塞状态有很大不同

    • 当线程等待另一个线程通知调度器一个条件时, 自己进入等待状态
    • 调用Object.waitThread.join, 或等待JUC库中的Lock或Condition时
  • Timed waiting(计时等待)

    因带有超时参数方法进入计时等待状态, 状态持续到超时期满或接收适当通知

    • Thread.sleep Object.wait Thread.join Lock.tryLockCondition.await计时版
  • Terminated(被终止)

    见上节

当一个线程被阻塞或等待或终止时, 另一个线程被调度为运行状态. 当另一个线程等待期满或成功获得锁, 调度器比较其与当前运行线程的优先级, 若高则从当前运行线程中挑选一个, 剥夺运行权, 运行一个新线程

线程属性

线程优先级

缺省线程继承其父类线程优先级, setPriority(int newPriority)提高或降低任何一个线程优先级. 优先级高度依赖运行系统, 如Linux下所有线程优先级相同.

应注意, 如果有几个高优先级未进入非活动状态, 每次选择运行新线程时都会选择高优先级, 可能会导致低优先级线程饿死.

static void yield( ), 让当前执行前线程处于让步状态. 若有其他线程至少高于该线程优先级, 这些线程接下来会被调度.

守护线程

线程启动之前调用t.setDaemon(true)

唯一用途是为其他线程提供服务. 当只剩下守护线程, 虚拟机则退出, 因为没有必要继续运行程序, 因此守护线程不能去访问固有资源, 如文件, 数据库, 因为它会在任何时候甚至一个操作中间中断.

未捕获异常处理器

run方法不能抛出任何受查异常, 但是非受查异常会导致线程终止. 线程死亡前异常会被传递到用于未捕获异常的处理器.

该处理器必须实现Tread.UncaughtExceptionHandler(内部接口)

  • Thread.setDefaultUncaughtExceptionHandler(...)为所有线程安装默认处理器
  • t.setUncaughtExceptionHandler(...)为该线程设置处理器
// Thread.java// 不设置默认处理器返回nullpublic static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){    return defaultUncaughtExceptionHandler;}// 独立线程不设置则返回该线程的ThreadGroup对象public UncaughtExceptionHandler getUncaughtExceptionHandler() {    return uncaughtExceptionHandler != null ? uncaughtExceptionHandler : group;}// ThreadGroup.java 不建议使用线程组public void uncaughtException(Thread t, Throwable e) {    if (parent != null) { // 调用父线程        parent.uncaughtException(t, e);    } else {        Thread.UncaughtExceptionHandler ueh =             Thread.getDefaultUncaughtExceptionHandler();        if (ueh != null) { // 调用默认的            ueh.uncaughtException(t, e);        } else if (!(e instanceof ThreadDeath)) { // 输出栈轨迹            System.err.print("Exception in thread \""                             + t.getName() + "\" ");            e.printStackTrace(System.err);        }    }}复制代码

参考: 《Java核心技术卷1》

转载于:https://juejin.im/post/5cd665716fb9a03214377dfc

你可能感兴趣的文章
sorry,you must have a tty to run sudo
查看>>
ios开发中使用正则表达式识别处理字符串中的URL
查看>>
项目中的积累,及常见小问题
查看>>
Python类型转换、数值操作(收藏)
查看>>
注释书写格式
查看>>
SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别
查看>>
2013=7=30 自增量的浅谈
查看>>
oracle11g dataguard 安装手册(转)
查看>>
java并发包分析之———Deque和LinkedBlockingDeque
查看>>
1. Two Sum - Easy - Leetcode解题报告
查看>>
SQLiteHelper
查看>>
多线程---同步函数的锁是this(转载)
查看>>
鱼C记事本V1.0(下)- 零基础入门学习Delphi28
查看>>
百练 2742 统计字符数 解题报告
查看>>
Ubuntu搜狗输入法候选词乱码
查看>>
js中回调函数写法
查看>>
React native android 最常见的10个问题
查看>>
数据结构和算法
查看>>
int a; int* a; int** a; int (*a)[]; int (*a)(int)
查看>>
.Net 项目代码风格要求
查看>>