JAVA多线程高并发总结

多线程

1.进程和线程的区别?
进程:是一个独立的环境,可以被看作一个程序或者一个应用。
线程:是一个进程中执行的一个任务
例如:打开360杀毒软件,它就是一个进程,它进行杀毒的时候就是一个线程。
语音:进程与线程的区别 --https://jingyan.baidu.com/article/624e74598efcc834e9ba5a66.html

2.线程的安全是什么
一个类或者程序提供的接口对于线程来说是个原子操作或者是多个线程之间切换不会导致接口执行结果存在二义性,也就是说我们不用考虑同步问题。

(1.)出现线程不安全的原因是什么?
如果我们创建多个线程,存在着共享数据,那么可能出现线程安全问题:当其中一个操作共享数据时,还未完成,另一个线程也进来了,这就会导致共享数据出问题。
(2.)线程安全解决办法?
数据共享完成时,其他线程就可以执行数据共享。
java提供了2个方式来实现同步同步互斥访问:
synchronized和Lock

3.创建线程的方式与区别
(1.)继承Thread类(如果继续了它,就无法继承其他类,所有要继承其他类就不必须创建一个线程,来实现Runable接口方式)
(2.)实现Runable接口(创建线程可以处理同一资源共享,JDK1.0)
(3.)实现Callable接口(创建线程可以获取线程执行的返回值,是否执行完成的信息,JDK1.5增加)
(4.)通过线程池创建线程

4.Thread类中的start()和run方法有什么区别?
Start():是一个启动线程。它是一个运行状态,但是并没有运行,这里的方法run()称为run()线程体,包含了线程内容run方法结束线程就终止。
run()可以重复调用,如果直接调用run方法,不会启动新线程,主线程只有一个线程执行路径只有一条,还是需要顺序执行。
区别:
start:可以启动一个新线程,不能被重复调用,实现了多线程。
run:不能启动新线程,可以被重复调用,没有实现多线程。

JAVA 多线程中调用wait()和sleep()方法有什么不同?
(1.)原理不同
sleep()方法是Thread类的静态方法,是线程用来控制自身流程的。
wait()方法是Object类的方法,用于线程间的通信
(2.)对锁的处理机制不同
调用wait()时候方法会释放当前持有的锁,而sleep方法不会释放锁。
(3.)使用地方不同
sleep可放任何地方,wait()方法必须放在同步方法或者异步方法
sleep方法必须捕获异常,wait(),notify(),notifyAll()不需要捕获异常。

     由于sleep不会释放锁标志,容易导致死锁问题的发生,一般情况下,不推荐使用sleep()方法,而推荐使用wait()方法

介绍一下CAS
CAS(Compare and Swap),比较与交换,实现并发算法时常用到的一种技术,是Java保证原子性的一种重要方法,也是一种乐观锁的实现方式

synchronized的使用方式有三种:
(1.)修饰同步代码块
(2.)修饰非静态的方法
(3.)修饰静态的方法

Lock和synchronized的区别
(1)synchronized是Java中的关键字,在JVM层面,而Lock是一个接口;
(2)synchronized会自动释放线程占有的锁,而Lock需要主动通过unLock()去释放锁,否则可能造成死锁现象。
(3)使用synchronized时,等待的线程会一直等待下去,不能够响应中断,而Lock可以让等待锁的线程响应中断;
(4)通过Lock可以判断锁状态,即是否成功获取锁,而synchronized无法判断。
(5)Lock可以提高多个线程进行读操作的效率。

synchronized和Lock底层实现?
synchronized用的锁是存在java对象里的,JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。
lock锁使用的是CAS和volatile来实现同步的,CAS使用硬件命令实现缓存一致性保证了原子性,volatile保证了可见性,多线程环境下所有的线程通过CAS进行竞争资源,只能有一个成功,其它的都会自旋。

在多线程中,什么是上下文切换?
上下文切换是存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。是多任务操作系统和多线程环境的基本特征。

并发编程三要素
1.原子性:要么执行成功要么执行失败。
2.有序性:按照先后顺序。
3.可见性:当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值。

Java中堆和栈有什么不同?(相对于线程来说)
  栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中存储的变量对其它线程是不可见的。
  堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

什么是线程池? 为什么要使用它?
线程池(thread pool):一种线程使用模式。
  创建线程要花费资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。
线程池的好处:
(1)通过重用线程池中的线程,来减少每个线程创建和销毁的性能开销。
(2)对线程进行一些维护和管理,比如定时开始,周期执行,并发数控制等等。

什么是ThreadLocal?
ThreadLocal用于创建线程的本地变量,我们知道一个对象的所有线程共享它的全局变量,所以这些变量是非线程安全的,我们可以使用同步技术。但是当我们不想使用同步的时候,我们可以选择ThreadLocal变量。每个线程都会拥有他们自己的Thread变量,它们可以使用get()/set()方法去获取他们的默认值或者在线程内部改变他们的值。

死锁是什么?如何避免死锁?
  死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:
1)互斥条件:一个资源每次只能被一个进程使用。
2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3)不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
  避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。
Java中notify 和 notifyAll有什么区别?
  调用notify时,只有一个等待线程会被唤醒而且它不能保证哪个线程会被唤醒,这取决于线程调度器。虽然如果你调用notifyAll方法,那么等待该锁的所有线程都会被唤醒

如何创建守护线程?
  守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件(百度百科)。
  Java线程分为两类分别为daemon线程(守护线程)和User线程(用户线程),在JVM启动时候会调用main函数,main函数所在的线程是一个用户线程,这个是我们可以看到的线程,其实JVM内部同时还启动了好多守护线程,比如垃圾回收线程。那么守护线程和用户线程有什么区别那?区别之一是当最后一个非守护线程结束时候,JVM会正常退出,而不管当前是否有守护线程,也就是说守护线程是否结束并不影响JVM的退出。言外之意是只要有一个用户线程还没结束正常情况下JVM就不会退出。

什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?
 线程调度器是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。
 时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。分配CPU时间可以基于线程优先级或者线程等待的时间。线程调度并不受到Java虚拟机控制,所以由应用程序来控制它是更好的选择(即最好不要让你的程序依赖于线程的优先级)

Java线程池中submit() 和 execute()方法有什么区别?
  两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。

什么是FutureTask?
  在Java并发程序中FutureTask表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能取回,如果运算尚未完成get方法将会阻塞。一个FutureTask对象可以对调用了Callable和Runnable的对象进行包装,由于FutureTask也是调用了Runnable接口所以它可以提交给Executor来执行。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值