作业2

作者: 滔滔逐浪 | 来源:发表于2020-07-15 09:05 被阅读0次

013-每特教育&蚂蚁课堂-第七期-从零开始学习多线程技术-多线程技术快速入门

  1. 什么是多线程
  在同一个进程开启了多条不同的执行路径,每条执行路径就是一个线程,多条不同路径同时执行

  1. 进程与线程的区别
进程就是系统中正在运行的一个程序,程序一旦运行就是一个进程,在一个进程中可以开启多个不同的线程执行。

  1. 多线程与单线程的区别
单线程:就是使用一条线程从上到下执行完代码,效率比较低,且响应也比较慢,对用户不是很友好。
多线程:开启多条不同的线程,每个线程执行不同的任务,每个线程之间相互不影响。

  1. 如何理解cpu切换概念
 对于单核的CPU来说,CPU在同一个时刻只能够运行一个线程,当正在运行的线程切换到另外一个线程时,这个过程我们可以理解为CPU上下文切换。
  1. 多线程创建四种方式
1.继承Thread类
2.使用Runnable
3.使用Callable
4.线程池的方式

  1. 如何创建线程带返回结果

package com.taotao.zuoye.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 *@author tom
 *Date  2020/7/15 0015 7:39
 *
 */
public class MyCallable  implements Callable<String> {
    @Override
    public String call() throws Exception {
        try {
            Thread.sleep(3000);
        }catch (Exception e){
            e.getCause();
        }
        return "异步发送短信成功";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask=new FutureTask<String>(new MyCallable());
         Thread thread=new Thread(futureTask);
         thread.start();
         String result=futureTask.get();
        System.out.println(result);

    }
}

  1. 用户线程与守护线程的区别
Java内创建的线程默认是bai创建用户线程,比如dunew Thread(线程对象).start
用户线程,不zhi随着其他人的死亡而死亡,只有两种情况死dao掉,1在run中异常终止,而正常把run执行完毕。线程死亡
守护线程,随着用户线程的死亡而死亡,当用户线程死完了守护线程也死了,比如gc垃圾回收线程。用户线程存在,那gc就有活着的必要,反之间用了
用户线程呢?就是一根筋的运行着,不会受到外界干扰自己运行自己的就行了
守护线程呢?更多的就是运行在最后才死亡
用哪一种呢?得看你干什么事情,一半是自己做自己事儿就按默认用户线程走了
还有一个概念是,用户进程和守护进程,简而言之就是,守护进程能跟随操作系统的死亡而死亡脱离控制台的捆绑命运。而用户进程控制台一关运行的程序都死掉了。
守护进程和守护线程很相似,都是为了守护到最后,守护到死亡
守护线程:守护到所有非守护(用户)线程死掉
守护进程:守护到主进程死掉

  1. 多线程五种状态分析
多线程五种的状态


1.当我们新建一个线程的时候,new Thread的时候为新建的状态。
2.当我们调用到start方法的时候,不会立马执行到我们的run方法,当前线程状态为就绪状态,需要等待cpu的切换。
3.当cpu切换能够调用到该线程的时候,当前线程的状态
为运行状态。
4.当我们在线程调用sleep方法的时候,当前线程线程的状态为
阻塞状态,当休眠的时候过了的时候有需要从新等待cpu调度,从就绪状态到运行。
5.当我们线程调用stop方法或者run方法代码执行结束的时候
当前线程的状态为死亡状态。

014-每特教育&蚂蚁课堂-第七期-从零开始学习多线程技术-多线程线程安全问题

  1. 什么是线程安全问题

当多个线程同时共享同一个全局变量做写的操作时候,可能会受到其他线程的干扰。
  1. 如何解决线程安全问题
          解决办法:
1.使用java锁的机制 Synchronized、或者Lock锁 还有CAS无锁机制。
2.
对于代码中如果在多线程同时执行操作的情况下,可能会受到其他线程的干扰的代码采用锁的机制,在同一个时刻只能保证只有一个线程去执行。也就是只要获取到锁的之后,才能够进入该代码块执行,代码执行完之后释放锁之后其他线程才可以执行。
3.没有获取到锁的线程,则一直会排队阻塞,整个过程是一个悲观状态。

  1. Synchronized与Lock锁的区别
     1,synchronized 属于java关键字,而lock 锁是基于aqs封装的一个锁的框架
     2,Synchronized当代码执行结束自动释放锁,而lock需要人工释放锁,相对于来说lock 锁比较灵活,



  1. 多线程死锁线程产生的原因
在同步中嵌套同步,会出现死锁的现象。
package com.taotao.zuoye.thread;

/**
 *@author tom
 *Date  2020/7/15 0015 22:45
 *
 */
public class Thread004  implements  Runnable {
    private  static  int count=100;
     private  Boolean flag=true;
     private  Object object=new Object();

    @Override
    public void run() {
        if(flag){
            while (count>0){
                synchronized (object){
                    try {
                             Thread.sleep(10);
                    }catch (Exception e){
                        e.getCause();
                    }
                    ticket();
                }
            }

        }else {
            while (count>0){
                ticket();
            }
        }




    }

    private  synchronized void ticket() {
        synchronized (object){
            try {

                Thread.sleep(10);
            }catch (Exception e){
                e.getCause();
            }
            if(count>0){
                System.out.println(Thread.currentThread().getName()+",正在开始出售:"+(100-count+1));
                count--;
            }

        }


    }

    public static void main(String[] args) {
        Thread004 thread004=new Thread004();
        new Thread(thread004,"窗口1").start();
        try {
            Thread.sleep(40);
            thread004.flag=false;
        }catch (Exception e){
            e.getCause();
        }
         new Thread(thread004,"窗口2").start();

    }
}

  1. 多线程如何排查死锁的现象
查找到当前JVm 环境变量: C:\Program Files\Java\jdk1.8.0_131\bin 找到
jconsole.exe工具,

image.png

015-每特教育&蚂蚁课堂-第七期-从零开始学习多线程技术-多线程之间如何实现通讯

  1. wait与notify区别
1, 因为涉及到对象锁,wait, Notify 必须要在synchronized 中使用
2, Wait 会暂停当前线程,释放cpu执行资格,同时释放锁
3,notify 唤醒锁池正在等待的线程。

  1. wait与sleep区别
对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

在调用sleep()方法的过程中,线程不会释放对象锁。

而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

从使用角度看,sleep是Thread线程类的方法,而wait是Object顶级类的方法。

sleep可以在任何地方使用,而wait只能在同步方法或者同步块中使用。

CPU及资源锁释放

sleep,wait调用后都会暂停当前线程并让出cpu的执行时间,但不同的是sleep不会释放当前持有的对象的锁资源,到时间后会继续执行,而wait会放弃所有锁并需要notify/notifyAll后重新获取到对象锁资源后才能继续执行。

sleep和wait的区别:
1、sleep是Thread的静态方法,wait是Object的方法,任何对象实例都能调用。
2、sleep不会释放锁,它也不需要占用锁。wait会释放锁,但调用它的前提是当前线程占有锁(即代码要在synchronized中)。
3、它们都可以被interrupted方法中断。


  1. join实现的原理
在main主线程中启动一个线程thread_01,而线程1中又新建了一个线程thread_02,执行thread_02.start()时启动了线程2;
当执行到thread_02.join()时,会让线程1进入阻塞等待状态,直到线程2全部执行完毕后,线程1才能执行;
join()方法的使用场景也就不言而喻了,即主线程等待子线程全部执行完毕后,才继续执行主线程后续的逻辑。    


016-每特教育&蚂蚁课堂-第七期-深入理解并发编程-javavolatile原理分析

  1. 快速回顾多核多cpu的概念
如果是单核的cpu的情况下,cpu在同一个时刻只能执行一个线程。
存在切换过程 底层并不是真正多线程。
多核 举个例子, 6核12线程  能够同时开启12个线程同时运行较少cpu切换。


  1. 线程不可见产生的原因
因为我们CPU读取主内存共享变量的数据时候,效率是非常低,所以对每个CPU设置
对应的高速缓存 L1、L2、L3  缓存我们共享变量主内存中的副本。
相当于每个CPU对应共享变量的副本,副本与副本之间可能会存在一个数据不一致性的问题。
比如线程线程B修改的某个副本值,线程A的副本可能不可见。导致可见性问题。
  1. java内存模型的Jmm定义
java 内存模型定义的是一种抽象概念,定义屏蔽java程序对不同的操作系统的内存访问差异。
主内存:
        存放我们共享变量的数据:
工作内存:
    每个cpu对共享变量(主内存)的副本。堆+方法区


jmm 八大同步规范:


image.png
(1)lock(锁定):作用于 主内存的变量,把一个变量标记为一条线程独占状态
(2)unlock(解锁):作用于 主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
(3)read(读取):作用于 主内存的变量,把一个变量值从主内存传输到线程的 工作内存中,以便随后的load动作使用
(4)load(载入):作用于 工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中
(5)use(使用):作用于 工作内存的变量,把工作内存中的一个变量值传递给执行引擎
(6)assign(赋值):作用于 工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量
(7)store(存储):作用于 工作内存的变量,把工作内存中的一个变量的值传送到 主内存中,以便随后的write的操作
(8)write(写入):作用于 工作内存的变量,它把store操作从工作内存中的一个变量的值传送到 主内存的变量中


  1. volatile关键字实现原理
通过汇编lock前缀指令触发底层锁的机制
锁的机制2种: 总线索/MSEI缓存一致性协议
主要帮助我们解决多个不同cpu之间三级花奴才能之间数据同步的问题:

  1. mesi数据一致性协议原理
1.M 修改 (Modified) 这行数据有效,数据被修改了,和主内存中的数据不一致,数据只存在于本Cache中。
2.E 独享、互斥 (Exclusive) 这行数据有效,数据和主内存中的数据一致,数据只存在于本Cache中。
3.S 共享 (Shared) 这行数据有效,数据和主内存中的数据一致,数据存在于很多Cache中。
4.I 无效 (Invalid) 这行数据无效。


E:独享:当只有一个cpu线程的情况下,cpu副本数据与主内存数据如果
保持一致的情况下,则该cpu状态为E状态 独享。
S:共享:在多个cpu线程的情况了下,每个cpu副本之间数据如果保持一致
的情况下,则当前cpu状态为S
M:如果当前cpu副本数据如果与主内存中的数据不一致的情况下,则当前cpu状态
为M
I: 总线嗅探机制发现 状态为m的情况下,则会将该cpu改为i状态 无效
该cpu缓存主动获取主内存的数据同步更新。

总线:维护解决cpu高速缓存副本数据之间一致性问题。






如果状态是M的情况下,则使用嗅探机制通知其他的CPU工作内存副本状态为I无效状态,则 刷新主内存数据到本地中,从而多核cpu数据的一致性。

017-每特教育&蚂蚁课堂-第七期-深入理解并发编程-volatile重排序与内存屏障

  1. volatile不保证原子性
  2. 为什么会产生重排序
  3. 重排序会遵循什么原则
  4. 重排序在多线程的情况下有那些影响
  5. 为什么单例需要加上volatile
  6. synchronized与volatile区别

018-每特教育&蚂蚁课堂-第七期-深入理解并发编程-悲观锁&乐观锁&公平锁&非公平锁&自旋转锁原理

  1. 锁的分类有那些
  2. mysql中的事务如果是做begin,不回滚也提交会发生什么情况
  3. 如何处理mysql行锁的问题
  4. mysql中的行锁在什么时候释放
  5. 乐观锁与悲观锁的区别
  6. 公平锁与非公平锁的区别
  7. 什么是锁的可重入性
  8. 共享锁的特征

019-每特教育&蚂蚁课堂-第七期-深入理解并发编程-站在C++源码角度分析synchronized锁的原理

  1. 什么是CAS
  2. CAS保证原子性
  3. 什么是自旋锁
  4. 自旋锁有那些问题
  5. CAS有那些有缺点
  6. 原子类底层实现原理
  7. CAS如何解决ABA的问题

020-每特教育&蚂蚁课堂-第七期-深入理解并发编程-synchronized的monitor与对象布局原理分析

  1. synchronized实现原理
  2. synchronized monitor对象作用
  3. java对象 内存如何布局
  4. new 一个对象占多少字节
  5. 对象头存放了那些内容

021-每特教育&蚂蚁课堂-第七期-深入理解并发编程-synchronized锁竞争偏向锁轻量锁重量锁原理分析

  1. synchronized一定是为重量锁吗
  2. synchronized锁的进化过程
  3. synchronized 偏向锁、轻量锁 重量锁 区别
  4. 锁消除与粗化
  5. synchronized优化点

022-每特教育&蚂蚁课堂-第七期-深入理解并发编程-深入分析AQS实现原理、
023-每特教育&蚂蚁课堂-第七期-深入理解并发编程-AbstractQueuedSynchronizer源码解读

  1. Lock底层是如何实现?
  2. Lock默认是公平锁还是悲观锁
  3. 简单谈谈AQS框架
  4. AQS在那些地方有用到过
  5. AQS加锁、解锁原理
  6. AQS如何实现公平锁与非公平锁
  7. AQS底层是采用单向还是双链表存放正在等待的线程

相关文章

网友评论

      本文标题:作业2

      本文链接:https://www.haomeiwen.com/subject/dytwcktx.html