美文网首页
JAVA多线程

JAVA多线程

作者: 飞马_6886 | 来源:发表于2019-07-07 23:49 被阅读0次

基本概念

进程和线程

进程是程序运行资源分配的最小单位:进程是操作系统进行资源分配的最小单位,资源包括cpu,内存空间,磁盘IO等,同一进程中的多条线程共享该线程中的全部系统资源。
线程是cpu调度的最小单位,必须依赖于进程而存在。线程是进程的一个实体,是CPU调度和分配的基本单位,他是比进程更小的能独立运行的基本单位。

启动线程的三种方式:

1,extends Thread, 然后run
2, implements Runnable;然后交给Thread运行
3 ,implements Callable; 然后交给Thread运行
下面各举例说明一下:

//第一种方式:  声明线程类
public class MyThread extends Thread{
            @Override
        public void run() {
            super.run();
            //do somework
        }
}
// 启动:
MyThead mThread = new MyThread();
mThread.start();
//方式二:
public class RunThread implements Runnable{
      @Override
        public void run() {
            System.out.print("run run run....");
        }
}
//调用和启动:
RunThread mRunThread = new RunThread();
new Thread(mRunThread).start();
//方式三:
public CallableThread implement Callabe<String>{
            @Override
        public String call() throws Exception {
            return "CallThread";
        }
}
//调用和启动:
CallableThread mCallThread = new CallableThread();
FutureTask<String>  mTask = new FutureTask<>(mCallThread);
new Thread(mTask).start();
//接收返回参数
String param = mTask.get();

线程的终止:

1.自然终止:当线程run执行完了,或者抛出一个未处理的异常导致线程提前终止。
2 调用api方法时线程终止。其中有suspend() ,resume(),stop() .这些方法都是过时的,也是不建议使用的。以suspend()为例,调用后线程不会释放已经占有的资源,比如锁,而是占着资源进入睡眠状态,这样容易引发死锁问题。而stop()方法,结束一个线程时,不能保证所占资源正常释放, 通常是没有给线程完成任务释放资源的机会,程序会工作在不确定的状态下。因此不建议使用这些过时的方法。

安全的中止则是 其他线程调用某个线程A的interrupt()方法,对其进行中断操作,好比是其他线程对A线程打个招呼,“嘿 伙计 你要暂停了”。但是A不一定会立即中止,A完全可以不用理会这种中断请求,因为Java 线程是协作式的 不是抢占式的。 线程通过检查自身中断标示位是否被置为true来进行响应,通过方法 isInterrupted(), 来判断是否被中断,。
也可以通过调用静态方法Thread.interrupted(),来判断当前线程是否被中止,不过此方法会将自身中断标示位置为false。

不建议使用标示位来中断线程,因为run()方法里如果有阻塞操作时,无法很快检测到取消标识。要等阻塞执行完成后才会检测阻塞标识。这种情况使用中断会更好,1.一般的阻塞方法如sleep支持中断的检查,2,检查中断位的状态和检查取消标志位没什么区别,使用中断还可以避免声明取消标示位,减少资源的消耗。

处于死锁状态的线程无法被中断

对其他方法的理解

run()和 start()
start()才会开启运行一个线程,调用start方法后使线程进入就绪状态,等待分派资源cpu等资源,进入运行时才会调用实现了的 run方法。start不能被重复调用。
run只是调用类内部的一个成员方法。可以重复执行,可以单独调用。

yield()方法:
使当前线程让出cpu占有权,单让出时间是不可确定的。也不会释放锁资源,所有执行yield方法的线程进入可执行状态后有可能马上又被执行。

join():
把指定的线程加入到当前线程,可以使两个交替的执行的线程合并成顺序执行。比如在线程B中调用了线程A的join()方法,那么要等A线程执行完后,才会执行B线程。

wait()
调用该方法后,线程会进入等待状态,只有等待其他线程通知或被中断才会返回。注意 调用wait会释放对象的锁

notify()
通知一个在对象上等待的线程,使其从wait方法返回,而返回的前提是该线程获得了对象的锁,没有获得对象锁的线程会重新进入等待状态。

notifyAll()
通知所有等待在该对象上的线程。

线程池

public ThreadPoolExecute(
      int corePoolSize,
      int maximumPoolSize,
      long keepAliveTime,
      TimeUnit unit,
      BlockingQueue<Runnable> workQueue,
      ThreadFactory threadFactory,
      RejectedPolicyHandler handler
)
各参数意义:
corepoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:线程空闲时存活的时间,默认情况下该参数只在线程数大于corePoolSize时有效。
TimeUnit:keepAliveTime的时间单位
workQueue:必须是BlockingQueue阻塞队列,尽量使用有界队列。
threadFactory:创建线程的工厂,
handler : 拒绝策略 JDK实现了四种 
   1. AbortPolicy:直接抛出异常,也是默认的策略。
    2.CallerRunsPolicy:用调用者所在的线程来执行
    3.DiscardOldestPolicy:丢弃阻塞队列中最靠前的任务,并执行当前任务
    4.DiscardPolicy:直接丢弃任务。
  当然也可以实现RejectPolicyHandler接口,自定义饱和策略。

任务特性:
Cpu密集型 机器的CPU核心数(顶多+1) (页缺失)Runtime.getRuntime().availableProcessor 可以获取核心数。
IO密集型 : cpu核心数 * 2(经验值)
混合型: 时间相差不大 拆分成两个线程池 ,相差大 忽略时间少的

悲观锁与乐观锁

synchronized 与 lock 都是悲观锁,(上下文切换 耗时2万个时钟周期 3-5ms)
乐观锁 CAS ,自旋(死循环)(0.6ns )

只有synchronized 会进入阻塞(被动 ) lock是等待(主动)

死锁三个条件
多个操作者M 真多多个资源N N<=M
争夺资源顺序不对
拿到资源不放手

活锁:解决方法是:sleep随机数 几毫秒。

CAS(compare and swap)

原子操作:synchronized 是原子操作

cas问题:
ABA问题:A---》B--》A 解决:版本戳
开销问题:线程一直执行 开销很大
只能保证一个共享变量的原子操作 解决:将多个变量打包成一个变量

Java主流锁的分类:

锁的分类.jpg

相关文章

  • 带你搞懂Java多线程(五)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四) ...

  • 带你搞懂Java多线程(六)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四)带...

  • Java多线程目录

    Java多线程目录 Java多线程1 线程基础Java多线程2 多个线程之间共享数据Java多线程3 原子性操作类...

  • java多线程--Callable

    **移步[java多线程系列文章]Java多线程(二十二)---LockSupport工具Java 停止线程 一、...

  • android 多线程 — 线程的面试题和答案

    这里都是我从各个地方找来的资料,鸣谢: Java多线程干货系列—(一)Java多线程基础 JAVA多线程和并发基础...

  • 5月份第一周学习安排

    学习内容: java多线程及线程同步的方法(使用) java多线程各种同步方法的原理和优缺点 java多线程设计模...

  • 带你搞懂Java多线程(四)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三) 什么是线程间的协作 线程之间...

  • Java基础(六)

    多线程 Java多线程并发 1.1 JAVA 并发知识库 1.2 JAVA 线程实现/创建方式 1.2.1 继承 ...

  • (五) volatile关键字

    Java多线程目录 1 背景 理解Java多线程的内存抽象逻辑请阅读java多线程内存模型,当代操作系统,处理器为...

  • Java多线程高级特性(JDK8)

    [TOC] 一、Java多线程 1.Java多线程基础知识 Java 给多线程编程提供了内置的支持。一条线程指的是...

网友评论

      本文标题:JAVA多线程

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