并发编程之深入理解JAVA线程

一. 问题思考
1.CAS涉及到用户模式到内核模式的切换吗?

CAS机制的英文缩写是Compare and Swap,翻译一下就是比较和交换

CAS机制中使用3个基本操作数:内存地址V,旧的预期值A,要修改的新值B,更新一个变量的时候,只有当变量的旧的预期值A和内存地址V中的值相同的时候,才会将内存地址V中的值更新为新值B

Compare和Swap过程的原子性是通过unsafe类来实现的,unsafe类为我们提供了硬件级别的原子操作!
不涉及内核模式的切换
2.为什么说创建Java线程的方式本质上只有一种?Java线程和go语言的协程有什么区别?
最终都是new Thread()实现 
3.如何优雅的终止线程?
通过线程中断命令
设置标记位
Thread.currentThread().interrupt()
在线程内通过判断是否存在中断标志
Thread.currentThread().isInterrupted()
public static void main(String[] args)  {
    System.out.println("begin");
    Thread t1 = new Thread(new Runnable() {
        @Override
        public  void run() {
            while (true) {
                i++;
                System.out.println(i);
                //Thread.interrupted()  清除中断标志位
                //Thread.currentThread().isInterrupted() 不会清除中断标志位
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("说明有线程中断标志,可以跳出线程或执行对应逻辑");
                }
                if(i==10){
                    break;
                }
            }
        }
    });
    t1.start();
    //不会停止线程t1,只会设置一个中断标志位 flag=true
    t1.interrupt();
}
4.Java线程之间如何通信的,有哪些方式?
volatile wait() notify() notifyAll() LockSupport.park  LockSupport.unpark
二.线程有那几种状态
要分多种层面
操作系统层面:

JAVA层面:
1. NEW(初始化状态)
2. RUNNABLE(可运行状态+运行状态)JAVA已经将线程交给操作系统执行,是否真正已执行,并不能由JAVA管理
3. BLOCKED(阻塞状态)
4. WAITING(无时限等待)
5. TIMED_WAITING(有时限等待)
6. TERMINATED(终止状态)
三.线程相关
1.Java线程执行为什么不能直接调用run()方法,而要调用start()方法?
run方法此时只是一个对象的方法,如果直接调用,是由当前线程去执行,而不是新线程
start()此时才是真正去创建一个新线程(去操作系统申请创建线程)
2.Java线程属于内核级线程?
JDK1.2—— 基于操作系统原生线程模型来实现。Sun JDK,它的Windows版本和Linux版本
都使用一对一的线程模型实现,一条Java线程就映射到一条轻量级进程之中。
内核级线程(Kernel Level Thread ,KLT ):它们是依赖于内核的,即无论是用户进程中的线
程,还是系统进程中的线程,它们的创建、撤消、切换都由内核实现。
用户级线程(User Level Thread,ULT) :操作系统内核不知道应用线程的存在。
四.Thread常用方法
sleep
  1.调用sleep方法,线程会从running状态修改为 TIMED_WAITING,不会释放对象锁
  2.其他线程调用线程中断方法interrupt, 当前线程会抛出InterruptedException,并且会清除中断标
  3.睡眠结束后未必会立即执行
  4.如果sleep(0)传入的是0等同于yield
yield
  1.调用yield方法会从running(运行)状态改为runnable(就绪)状态,给其他高优先级线程执行,不会释放对象锁
  2.假设只有一个线程线程,又会立即执行
  3.具体实现是基于操作系统
join
   1. join()方法将挂起调用线程的执行,直到被调用的对象完成它的执行
 例子:线程2要等线程1先执行完,线程3要等线程2执行完
public static void main(String[] args) {
    Thread thread1 = new Thread(() -> System.out.println("thread1"));
    Thread thread2 = new Thread(() -> {
        try {
            thread1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread2");
    });
    Thread thread3 = new Thread(() -> {
        try {
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread3");
    });
    thread1.start();
    thread2.start();
    thread3.start();
}
等待唤醒(等待通知)机制
等待唤醒机制可以基于wait和notify方法来实现,在一个线程内调用该线程锁对象的wait方法,
线程将进入等待队列进行等待直到被唤醒
notify 不能指定线程
notifyall 会唤醒对象下全部线程
LockSupport是JDK中用来实现线程阻塞和唤醒的工具,线程调用park则等待“许可”,调用
unpark则为指定线程提供“许可”。 使用它可以在任何场合使线程阻塞,可以指定任何线程进行
唤醒,并且不用担心阻塞和唤醒操作的顺序,但要注意连续多次唤醒的效果和一次唤醒是一样
wait和sleep的区别?
wait是object的方法 sleep是Thread的方法
wait必须在同步块中使用
wait会释放对象锁

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值