• [交流分享] 常见的对比
    Runnable VS CallableCallable仅在 Java 1.5 中引入,目的就是为了来处理Runnable不支持的用例。Callable 接口可以返回结果或抛出检查异常Runnable 接口不会返回结果或抛出检查异常,如果任务不需要返回结果或抛出异常推荐使用 Runnable接口,这样代码看起来会更加简洁工具类 Executors 可以实现 Runnable 对象和 Callable 对象之间的相互转换。(Executors.callable(Runnable task)或 Executors.callable(Runnable task,Object resule))shutdown() VS shutdownNow()shutdown() :关闭线程池,线程池的状态变为 SHUTDOWN。线程池不再接受新任务了,但是队列里的任务得执行完毕。shutdownNow() :关闭线程池,线程的状态变为 STOP。线程池会终止当前正在运行的任务,并停止处理排队的任务并返回正在等待执行的 List。 shutdownNow的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终isTerminated() VS isShutdown()isShutDown 当调用 shutdown() 方法后返回为 true。isTerminated 当调用 shutdown() 方法后,并且所有提交的任务完成后返回为 true
  • [技术干货] [技术分享]进程树
    转载于:https://zh.wikipedia.org/wiki/%E8%BF%9B%E7%A8%8B%E6%A0%91进程树(Process tree)是计算机科学中的术语,又称为进程图(Process map)或进程家族树(Process graph),是一种表示进程关系的直观方法。进程树中的进程分为父进程和子进程两种基本类型。结构进程树的概念基于图论中的有向树的概念。一个进程树由若干个系统进程和它们之间的关系构成。进程树中的每个进程是树的节点。如果进程A创建了进程B,就称A是B的父进程,B是A的子进程。若一个进程不是任何其它进程的子进程,则称之为根进程或进程家族的祖先。实现在Windows任务管理器中,结束一个进程树的作用为结束这个进程和由它创生的子进程。
  • [算子开发] 【众智】【CANN】多线程测试错误
    我在进行多线程UT测试时,设定matrix的shape为[4,4,4,4],rhs的shape为[4,4,4,1],但最终输出结果不对,请问专家能不能帮忙查查错?
  • [新手课堂] 多线程中 synchronized 锁升级的原理是什么?
    synchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。
  • [新手课堂] synchronized的用法有哪些?
    修饰普通方法:作用于当前对象实例,进入同步代码前要获得当前对象实例的锁修饰静态方法:作用于当前类,进入同步代码前要获得当前类对象的锁,synchronized 关键字加到 static 静态方法和 synchronized(class)代码块上都是是给 Class 类上锁修饰代码块:指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁特别注意:①如果一个线程A调用一个实例对象的非静态 synchronized 方法,而线程B需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁②尽量不要使用 synchronized(String s) ,因为JVM中,字符串常量池具有缓冲功能
  • [交流分享] 什么是线程死锁?如何避免死锁?
    多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 死锁必须具备以下四个条件:互斥条件:该资源任意一个时刻只由一个线程占用。请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。不剥夺条件:线程已获得的资源在末使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。如何避免线程死锁?只要破坏产生死锁的四个条件中的其中一个就可以了破坏互斥条件 这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)破坏请求与保持条件 一次性申请所有的资源。破坏不剥夺条件 占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。破坏循环等待条件 靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。锁 排序 法:(必须回答出来的点) 指定获取锁的顺序,比如某个线程只有获得A锁和B锁,才能对某资源进行操作,在多线程条件下,如何避免死锁? 通过指定锁的获取顺序,比如规定,只有获得A锁的线程才有资格获取B锁,按顺序获取锁就可以避免死锁。这通常被认为是解决死锁很好的一种方法。使用显式锁中的ReentrantLock.try(long,TimeUnit)来申请锁
  • [交流分享] 为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法
    new 一个 Thread,线程进入了新建状态; 调用start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容,(调用 start() 方***启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。)这是真正的多线程工作。直接执行 run() 方把 run 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。 *调用 start 方法方可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。
  • [交流分享] Thread类中的yield方法有什么作用?
    Yield方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。它是一个静态方法而且只保证当前线程放弃CPU占用而不能保证使其它线程一定能占用CPU,执行yield()的线程有可能在进入到暂停状态后马上又被执行。
  • [新手课堂] synchronized 和 ReentrantLock 区别是什么?
    1.两者都是可重入锁可重入锁:重入锁,也叫做递归锁,可重入锁指的是在一个线程中可以多次获取同一把锁,比如: 一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法,而无需重新获得锁, 两者都是同一个线程每进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。2.synchronized 依赖于 JVM 而 ReentrantLock 依赖于 APIsynchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团队在 JDK1.6 为 synchronized 关键字进行了很多优化,但是这些优化都是在虚拟机层面实现的ReentrantLock 是 JDK 层面实现的(也就是 API 层面,需要 lock() 和 unlock() 方法配合 try/finally 语句块来完成)3.ReentrantLock 比 synchronized 增加了一些高级功能相比synchronized,ReentrantLock增加了一些高级功能。主要来说主要有三点:①等待可中断;②可实现公平锁;③可实现选择性通知(锁可以绑定多个条件)等待可中断.通过lock.lockInterruptibly()来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。 ReentrantLock默认情况是非公平的,可以通过 ReentrantLock类的ReentrantLock(boolean fair)构造方法来制定是否是公平的。ReentrantLock类线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。 在使用notify()/notifyAll()方法进行通知时,被通知的线程是由 JVM 选择的,用ReentrantLock类结合Condition实例可以实现“选择性通知”4.使用选择除非需要使用 ReentrantLock 的高级功能,否则优先使用 synchronized。synchronized 是 JVM 实现的一种锁机制,JVM 原生地支持它,而 ReentrantLock 不是所有的 JDK 版本都支持。并且使用 synchronized 不用担心没有释放锁而导致死锁问题,因为 JVM 会确保锁的释放
  • [新手课堂] synchronized 和 volatile 的区别是什么?
    volatile 解决的是内存可见性问题,会使得所有对 volatile 变量的读写都直接写入主存,即 保证了变量的可见性。synchronized 解决的事执行控制的问题,它会阻止其他线程获取当前对象的监控锁,这样一来就让当前对象中被 synchronized 关键字保护的代码块无法被其他线程访问,也就是无法并发执行。而且,synchronized 还会创建一个 内存屏障,内存屏障指令保证了所有 CPU 操作结果都会直接刷到主存中,从而 保证操作的内存可见性,同时也使得这个锁的线程的所有操作都 happens-before 于随后获得这个锁的线程的操作。两者的区别主要有如下:volatile 本质是在告诉 JVM 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。volatile 仅能使用在变量级别;synchronized 则可以使用在 变量. 方法. 和类级别的volatile 仅能实现变量的修改可见性,不能保证原子性;而synchronized 则可以 保证变量的修改可见性和原子性volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。volatile 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化。
  • [交流分享] 谈谈volatile的使用及其原理
    volatile的两层语义:volatile保证变量对所有线程的可见性:当volatile变量被修改,新值对所有线程会立即更新。或者理解为多线程环境下使用volatile修饰的变量的值一定是最新的。jdk1.5以后volatile完全避免了指令重排优化,实现了有序性。volatile的原理:获取JIT(即时Java编译器,把字节码解释为机器语言发送给处理器)的汇编代码,发现volatile多加了lock addl指令,这个操作相当于一个内存屏障,使得lock指令后的指令不能重排序到内存屏障前的位置。这也是为什么JDK1.5以后可以使用双锁检测实现单例模式。lock前缀的另一层意义是使得本线程工作内存中的volatile变量值立即写入到主内存中,并且使得其他线程共享的该volatile变量无效化,这样其他线程必须重新从主内存中读取变量值。
  • [交流分享] 线程阻塞的三种情况
    当线程因为某种原因放弃 CPU 使用权后,即让出了 CPU 时间片,暂时就会停止运行,知道线程进入可运行状态(Runnable),才有机会再次获得 CPU 时间片转入 RUNNING 状态。一般来讲,阻塞的情况可以分为如下三种:等待阻塞(Object.wait -> 等待队列)RUNNING 状态的线程执行 Object.wait() 方法后,JVM 会将线程放入等待序列(waitting queue);同步阻塞(lock -> 锁池)RUNNING 状态的线程在获取对象的同步锁时,若该 同步锁被其他线程占用,则 JVM 将该线程放入锁池(lock pool)中;其他阻塞(sleep/join)RUNNING 状态的线程执行 Thread.sleep(long ms) 或 Thread.join() 方法,或发出 I/O 请求时,JVM 会将该线程置为阻塞状态。当 sleep() 状态超时,join() 等待线程终止或超时. 或者 I/O 处理完毕时,线程重新转入可运行状态(RUNNABLE);
  • [交流分享] 线程死亡的三种方式
    正常结束run() 或者 call() 方法执行完成后,线程正常结束;异常结束线程抛出一个未捕获的 Exception 或 Error,导致线程异常结束;调用 stop()直接调用线程的 stop() 方法来结束该线程,但是一般不推荐使用该种方式,因为该方法通常容易导致死锁;
  • [新手课堂] 线程池的核心参数
    1,corePoolSize:线程池核心线程数最大值​        IO密集型 (某大厂实践经验)​            核心线程数 = CPU核数 / (1-阻塞系数)​        CPU密集型:​            核心线程数 = CPU核数 + 1​        IO密集型: 核心线程数 = CPU核数 * 2  ​    2,maximumPoolSize: 线程池最大线程数大小​    3,keepAliveTime: 线程池中非核心线程空闲的存活时间大小​    4, unit: 线程空闲存活时间单位​    5,workQueue: 存放任务的阻塞队列​    6,threadFactory :用于设置创建线程的工厂,可以给创建的线程设置有意义的名字,可方便排查问题
  • [新手课堂] 线程池的状态
    **RUNNING**- 该状态的线程池会接收新任务,并处理阻塞队列中的任务;- 调用线程池的shutdown()方法,可以切换到SHUTDOWN状态;- 调用线程池的shutdownNow()方法,可以切换到STOP状态;**SHUTDOWN**- 该状态的线程池不会接收新任务,但会处理阻塞队列中的任务;- 队列为空,并且线程池中执行的任务也为空,进入TIDYING状态;**STOP**- 该状态的线程不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;- 线程池中执行的任务为空,进入TIDYING状态;**TIDYING**- 该状态表明所有的任务已经运行终止,记录的任务数量为0。- terminated()执行完毕,进入TERMINATED状态**TERMINATED**- 该状态表示线程池彻底终止
总条数:756 到第
上滑加载中