多线程(未完待续)

并行和并发有什么区别?

并行是逻辑上的同时发生,他表示同某一个时间段内同时进行多个程序。

并发是物理上的同时发生,他表示在某一个时间点同时进行多个程序。

线程和进程的区别?

1、定义不一样,进程是执行中的一段程序,而一个进程中执行中的每个任务即为一个线程。

2、一个线程只可以属于一个进程,但一个进程能包含多个线程。

3、线程无地址空间,它包括在进程的地址空间里。

4、线程的开销或代价比进程的小。

守护线程是什么?

非守护线程一直在后台运行着,JVM 无法正常退出。

如果添加了主线程,当主线程退出时,JVM 会随之退出运行,守护线程同时也会被回收,即使你里面是个死循环也不碍事。

创建线程有哪几种方式?

继承Thread

实现Runable接口

实现Callable接口

说一下 runnable 和 callable 有什么区别?

Callable接口可以返回执行结果 ,Runable接口不能返回执行结果。

Callable接口的call()方法可以抛出异常,Runable接口的run()方法不能抛出异常。

callable接口可以调用Future.cancel方法取消执行,Runable接口不能。

线程有哪些状态?

新建 New方法创建

就绪 调用run()方法

阻塞 调用sleep() 、wait()、notify()、notifyAll()

运行 开始run()

死亡 shop()、run()、call()方法结束

sleep() 和 wait() 有什么区别?

sheep()必须要设置休眠时间,不释放锁,是 Thread的方法

wait()可以设置也可以不设置,释放锁,是Object的方法

notify()和 notifyAll()有什么区别?

notify()唤醒一个线程

notifyAll()唤醒全部线程

线程的 run()和 start()有什么区别?

仅仅封装了需要线程执行的代码,如果直接调用就是普通的方法

先开启线程,然后再由虚拟机屌用run()方法

创建线程池有哪几种方式?

newcachedthreadpool

newfixedthreadpool

newsinglethreadExecutor

newschedulethreadpool

线程池都有哪些状态?

running、shotdown、shop、tidying、terminated

线程池的5种状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。

  1. RUNNING:线程池一旦被创建,就处于 RUNNING 状态,任务数为 0,能够接收新任务,对已排队的任务进行处理。

  2. SHUTDOWN:不接收新任务,但能处理已排队的任务。调用线程池的 shutdown() 方法,线程池由 RUNNING 转变为 SHUTDOWN 状态。

  3. STOP:不接收新任务,不处理已排队的任务,并且会中断正在处理的任务。调用线程池的 shutdownNow() 方法,线程池由(RUNNING 或 SHUTDOWN ) 转变为 STOP 状态。

  4. TIDYING:

    • SHUTDOWN 状态下,任务数为 0, 其他所有任务已终止,线程池会变为 TIDYING 状态,会执行 terminated() 方法。线程池中的 terminated() 方法是空实现,可以重写该方法进行相应的处理。

    • 线程池在 SHUTDOWN 状态,任务队列为空且执行中任务为空,线程池就会由 SHUTDOWN 转变为 TIDYING 状态。

    • 线程池在 STOP 状态,线程池中执行中任务为空时,就会由 STOP 转变为 TIDYING 状态

  5. TERMINATED:线程池彻底终止。线程池在 TIDYING 状态执行完 terminated() 方法就会由 TIDYING 转变为 TERMINATED 状态。

img

线程池中 submit()和 execute()方法有什么区别?

submit(Callable<T> task)、submit(Runnable task, T result)、submit(Runnable task)归属于ExecutorService接口。 execute(Runnable command)归属于Executor接口。ExecutorService继承了Executor。

  • submit()有返回值。

  • execute没有返回值。

  • submit()方便做异常处理。通过Future.get()可捕获异常。

线程的安全性问题体现在:

<!--没有会-->

原子性:一个或者多个操作在 CPU 执行的过程中不被中断的特性 可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到 有序性:程序执行的顺序按照代码的先后顺序执行

导致原因:

缓存导致的可见性问题 线程切换带来的原子性问题 编译优化带来的有序性问题

解决办法:

JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题 synchronized、volatile、LOCK,可以解决可见性问题 Happens-Before 规则可以解决有序性问题

Happens-Before 规则如下:

程序次序规则:在一个线程内,按照程序控制流顺序,书写在前面的操作先行发生于书写在后面的操作 管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作 volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作 线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作 线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生 对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始

多线程锁的升级原理是什么?

没有优化以前,synchronized是重量级锁(悲观锁),使用 wait 和 notify、notifyAll 来切换线程状态非常消耗系统资源;线程的挂起和唤醒间隔很短暂,这样很浪费资源,影响性能。所以 JVM 对 synchronized 关键字进行了优化,把锁分为 无锁、偏向锁、轻量级锁、重量级锁 状态。

无锁:没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功,其他修改失败的线程会不断重试直到修改成功。

偏向锁,指的就是偏向第一个加锁线程,该线程是不会主动释放偏向锁的,只有当其他线程尝试竞争偏向锁才会被释放。

轻量级锁:当锁是偏向锁的时候,被第二个线程 B 所访问,此时偏向锁就会升级为轻量级锁,线程 B 会通过自旋的形式尝试获取锁,线程不会阻塞,从而提高性能。

重量级锁:指当有一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态

什么是死锁?

死锁产生的原因:多线程以及多进程改善了系统资源的利用率并提高了系统的处理能力。然而,并发执行也带来了新的问题--死锁。 什么是死锁:所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。

怎么防止死锁?

  1. 有序资源分配法

必须为所有资源统一编号,同类资源必须一次申请完,不同类资源必须按顺序申请。

  1. 银行家算法

  2. 顺序加锁

    按照顺序加锁是一种有效的死锁预防机制。但是,这种方式需要事先知道所有可能会用到的锁,但总有些时候是无法预知的,所以该种方式只适合特定场景。

  3. 限时加锁

    若超过这个时间则放弃对该锁请求

ThreadLocal 是什么?有哪些使用场景?

ThreadLocal 是线程本地存储,提供线程局部变量,在每个线程中都创建了一个 ThreadLocalMap 对象,每个线程可以访问自己内部 ThreadLocalMap 对象内的 value。

使用场景:

为每个线程分配一个 JDBC 连接 Connection。这样就可以保证每个线程的都在各自的 Connection 上进行数据库的操作,不会出现 A 线程关了 B线程正在使用的 Connection; 还有 Session 管理 等问题。

说一下 synchronized 底层实现原理?

Volatile和synchronized的区别: 

  (1)、volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。   (2)、volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以包证。   (3)、volatile不会造成线程阻塞。synchronized可能会造成线程阻塞。   (4)、在性能方面synchronized关键字是防止多个线程同时执行一段代码,就会影响程序执行效率,而volatile关键字在某些情况下性能要优于synchronized。 synchronized是JVM层面实现的,java提供的关键字,Lock是API层面的锁。

synchronized 和 Lock 有什么区别?

synchronized不需要手动释放锁,底层会自动释放,

Lock则需要手动释放锁,否则有可能导致死锁

synchronized等待不可中断,除非抛出异常或者执行完成,抛出异常,jvm会自动要求释放锁。所以不存在死锁

Lock可以中断,通过interrupt()可中断

synchronized是非公平锁

Lock是默认公平锁,当传入false时是非公平锁

synchronized不可绑定多个条件

Lock可实现分组唤醒需要唤醒的锁

lock可以进行多线程拿到读锁,而写锁只有一个。读写分离

而synchronized只能单一化执行

synchronized 和 ReentrantLock 区别是什么?

说一下 atomic 的原理?

atomic 通过CAS (Compare And Wwap)乐观锁机制-自旋锁(它的实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值,并返回 true。否则,返回 false。)保证原子性,【通过降低锁粒度(多段锁)增加并发性能。这一点是java8做出的改进】从而避免 synchronized 的高开销,执行效率大为提升。

java多线程中的三个特性:

  原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

  可见性:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

  有序性:就是程序执行的顺序按照代码的先后顺序执行。一般来说处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值