Java面试题2.0--多线程

 
 什么是线程?
 
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。
 

线程和进程有什么区别?

线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。
 
创建线程有几种方式
方式一,继承 Thread 类创建线程类。
方式二,通过 Runnable 接口创建线程类。
方式三,通过 Callable 和 Future 创建线程。
 

用Runnable还是Thread?

Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口好了。
 
Thread 类中的start() 和 run() 方法有什么区别?
 
start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。
 

Java中如何停止一个线程?

当run() 或者 call() 方法执行完的时候线程会自动结束
如果要手动结束一个线程,你可以用volatile 布尔变量或设置某个变量达到一定值的时候,来退出run()方法的循环或者是取消任务来中断线程。
抛出异常
 
守护线程是什么:
 
是一种特殊的线程,它的作用有陪伴的含义。当进程中不存在非守护线程了,则守护线程自动销毁。守护线程的作用就是为其他线程的运行提供便利的服务,只有当最后一个非守护线程结束之后,守护线程才会结束,最典型的应用就是GC(垃圾回收器)
 
守护线程会等主线程结束之后才会销毁
 
什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?
线程调度器是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。分配CPU时间可以基于线程优先级或者线程等待的时间。线程调度并不受到Java虚拟机控制,所以由应用程序来控制它是更好的选择(也就是说不要让你的程序依赖于线程的优先级)。
 
什么是线程安全? 
 
当多个线程同时共享,同一个 全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题。
 
Synchronized:
 
当Synchronized关键字修饰一个方法的时候,该方法叫做同步方法:java中的每个对象都有一个锁(lock)或者叫做监视器(monitor),当访问某个对象的synchronized方法的时候,表示将对象上锁,此时其它任何线程都无法再去访问synchronized方法了,直到之前的那个线程执行方法完毕后(或者是抛出了异常),那么将该对象的锁释放掉,其他线程才有可能再去访问该synchronized方法。
 
如果一个对象有多个synchronized方法,某一个时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕前,其它线程是无法访问该对象的任何synchronzed方法的。
 
如果某个Synchronized方法是static的,那么当线程访问该方法时,它锁的并不是Synchronized方法所在的对象,而是Synchronized方法所在的对象所对象的Class对象,因为java中无论一个类有多少个对象,这些对象会对应唯一一个class对象,因此当线程分别访问同一个类的两个对象的两个static Synchronized方法的时候,他们执行的顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始执行。
 
synchronized方法和块比较
 
synchronized方法是一种粗粒度的并发控制,某一个时刻,只能有一个线程执行该synchronized方法,而synchronized块则是一种细粒度的并发控制,只会将块中的代码同步,位于方法内,synchronized块外之外的代码是可以被多个线程同时访问到的。
 
synchronized 的原理是什么?有什么不足?
 
synchronized是 Java 内置的关键字,它提供了一种独占的加锁方式。
 
synchronized的获取和释放锁由JVM实现,用户不需要显示的释放锁,非常方便。
然而,synchronized 也有一定的局限性。
当线程尝试获取锁的时候,如果获取不到锁会一直阻塞。
如果获取锁的线程进入休眠或者阻塞,除非当前线程异常,否则其他线程尝试获取锁必须一直等待。
好处:解决了多线程的安全问题 
弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源
 
synchronized使用前提是什么?有哪些注意事项?
1,必须要有两个或者两个以上的线程 
2,必须是多个线程使用同一个锁 
必须保证同步中只能有一个线程在运行 
 
对象监视器是什么?
 
将任意对象作为对象监视器,即可以定义任意一个对象,在synchronized(object){}中实现同步功能,object为任意类型的对象。
关键字synchronized还可以应用在static静态方法上。如果是加到static静态方法上则是给class类上锁,而加到非静态方法上是给对象上锁。
 
什么是静态同步函数?
 
方法上加上static关键字,使用synchronized 关键字修饰 或者使用类.class文件。
静态的同步函数使用的锁是  该函数所属字节码文件对象 
可以用 getClass方法获取,也可以用当前  类名.class 表示。
被static修饰的静态同步函数,不是使用的this锁,而是锁住的当前字节码文件,就是当前的class文件
多个对象会持有同一把锁吗?
多个对象多个锁:关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法当做锁。哪个线程先执行带有synchronized关键字的方法,哪个线程就持有该方法所属对象的锁lock,那么其他线程只能持等待状态,但前提是多个线程访问的是同一个对象。
 
  如果同步块内的线程抛出异常会发生什么?
 
无论你的同步块是正常还是异常退出的,里面的线程都会释放锁。
 
死锁的原因是什么?
 
在申请锁时发生了交叉闭环申请。即线程在获得了锁A并且没有释放的情况下去申请锁B,这时,另一个线程已经获得了锁B,在释放锁B之前又要先获得锁A,因此闭环发生,陷入死锁循环。
同步中嵌套同步,互相不释放
 
死锁发生的条件
 
死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:
互斥条件:一个资源每次只能被一个进程使用。
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
 
怎样避免死锁?
 
避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。

 Java中活锁和死锁有什么区别?

活锁和死锁类似,不同之处在于处于活锁的线程或进程的状态是不断改变的,活锁可以认为是一种特殊的饥饿。一个现实的活锁例子是两个人在狭小的走廊碰到,两个人都试着避让对方好让彼此通过,但是因为避让的方向都一样导致最后谁都不能通过走廊。简单的说就是,活锁和死锁的主要区别是前者进程的状态可以改变但是却不能继续执行。
 

 怎么检测一个线程是否拥有锁?

在java.lang.Thread中有一个方法叫holdsLock(),它返回true如果当且仅当当前线程拥有某个具体对象的锁。
 
多线程的脏读是什么?
虽然在赋值时进行了同步,但是在读取值时,有可能出现意外。在读取实例变量时,此值已经被其他线程更改过了。
当写数据的方法被synchronized变为同步后,读数据的方法没有被synchronized修饰,就有可能出现脏读。 </
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值