多线程:(三)并发编程常见面试题!

一、在Java中守护线程和用户线程的区别?

       Java中的线程分为两种:

       守护线程(Daemon)和用户线程(User)。

       任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(boolon); 设置为 true 则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon(boolon); 必须在Thread.start()之前调用,否则运行时会抛出异常。

       两者的区别:

  1. 唯一的区别是判断虚拟机(JVM)何时离开,Daemon是为其他线程提供服务,如果全部的User Thread 已经结束,Daemon没有可服务的线程,JVM关闭。
  2. Thread Dump 打印出来的线程信息,含有daemon字样的线程即为守护线程。

二、什么是多线程中的上下文切换

        多线程会共同使用一组计算机上的CPU,而线程数大于给程序分配的CPU数量时,为了让各个线程都有执行的机会,就需要轮转使用CPU。不同的线程切换使用CPU发生的切换数据等 就是 上下文切换。

三、死锁与活锁的区别,死锁与饥饿的区别

死锁:

        是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,他们将无法推进下去。

产生死锁的必要条件:

  1. 互斥条件:所谓互斥就是进程在某一时间内独占资源。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获取的资源保持不放。
  3. 不剥夺条件:进程已获得资源,在未使用完前,不能强行剥夺。
  4. 循环等待条件:若干个进程之间形成一种头尾相接的循环等待资源关系。

活锁:

        任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直“循环”的重复尝试,失败。

死锁和活锁的区别:

处于活锁的实体是在不断的改变状态,指“活”锁,而处于死锁的实体表现为等待;活锁有可能自行解开,死锁则不能。

饥饿

一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行的状态。

四、synchronized的底层原理

        synchronized(this)原理:涉及两条指令:monitorenter,monitorexit;

        同步方法:通过反编译结果看,方法同步并没有通过指令monitorenter 和 monitorexit 来实现,相对普通方法,常量池多了ACC_SYNCHRONIZED  标示符。

        JVM就是根据该标示符来实现方法同步的:当方法被调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取 monitor(监听),获取成功之后才能执行方法体,方法执行完后再释放 monitor。在方法执行期间,其他任何线程都无法再获得同一个 monitor 对象。

五、什么是线程组,为什么在Java中不推荐使用?

        ThreadGroup类,可以把线程归属到某一个线程组中,线程组中可以使用线程对象,也可以使用线程组,组中还可以使用线程,这样的组中结构有点类似于树的形式。

1、线程组 ThreadGroup对象中比较有用的方法是stop、resume、suspend等方法,由于这几个方法会导致线程的安全问题(主要是死锁问题),已经被官方废弃掉了,所以线程组本身的应用价值就大打折扣了。

2、线程组 ThreadGroup 不是线程安全的,在使用过程中获取的信息并不全是及时有效的,这就降低了它的使用价值。

六、什么是阻塞队列?阻塞队列的实现原理是什么?如何使用阻塞队列来实现生产者-消费者模型?

        阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。

        这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。

        阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。

        没记错的话 JDK7提供了7个阻塞队列。在实现上,主要是利用了Condition和Lock的等待通知模式。

七、什么是Callable 和 Future?

        Callable接口类似于Runnable,但Runnable不会返回接口,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说---Future可以拿到异步执行任务的返回值。

        可以认为是带有回调的Runnable。

        Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于生产结果,Future用于获取结果。

八、什么是FutureTask?

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

Callable<DispatchCarDO> queryDispatchCarInfo = new Callable<DispatchCarDO>() {
		@Override
		public ResultBaseType<Integer> call() throws Exception {
		// TODO
		DispatchCarDO dispatchCarDO = new DispatchCarDO();
		dispatchCarDO.setJihuaId(model.getJihuaId());
		dispatchCarDO.setChepai(model.getChepai());
		ResultBaseType<Integer> dispatchCarInfo = 
        iDispatchCarService.updateRfidByJobId(dispatchCarDO, token);
		return dispatchCarInfo;
	}
};
FutureTask<DispatchCarDO> queryInfoTask = new FutureTask<>(queryDispatchCarInfo);
new Thread(queryDispatchCarInfoTask).start();
queryDispatchCarInfoTask.get();

九、什么是并发容器的实现?

       何为同步容器:可以见到那地裂解为通过 synchronized 来实现同步的容器,如果有多个线程调用同步容器的方法,ta们将会串行执行。如: Vector、HashTable、以及 Collections.synchronizedSet,synchronizedList等方法返回的容器。

       并发容器使用了与同步容器,完全不同的加锁策略来提供更高的并发性和伸缩性,例如在ConcurrentHashMap中采用了一种粒度更细的加锁机制,可以称为分段锁,在这种锁机制下,允许任意数量的读线程并发访问map,并且执行读操作的线程和写操作线程也可以并发的访问map,同时允许一定数量的写操作线程并发的修改map,所以ta可以在并发环境下实现更高的吞吐量。

十、多线程同步和互斥有几种实现方法?

        线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当ta没有得到另一个线程的消息时应等待,直到消息到达才被唤醒。

        线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排他性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其他要使用该资源的线程必须等待,直到占有资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。

        线程间的同步方法大体可分为两类:用户模式和内核模式。 内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。

        ①用户模式下的方法有:原子操作(一个单一的全局变量),临界区;

        ②内核模式下的方法有:事件,信号量,互斥锁

十一、为什么我们调用start()方法时会执行run()方法,为什么不能直接调用run()方法?

         当调用start()方法时将创建新的线程,并且执行在run()方法里的代码。

         如果直接调用run()方法,ta不会创建新的线程  也不会执行调用线程的代码,只会把run()方法当作普通的方法去执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值