Java 多线程抢占 编程_Java并发编程 - 多线程/并发面试题集合(持续更新)

1. 现在有线程T1、T2和T3。你如何确保T2线程在T1之后执行,并且T3线程在T2之后执行。

2. Java 中新的Lock接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。

Lock接口的最大优势是它为读和写提供两个单独的锁(ReentrantReadWriteLock),ReentrantReadWriteLock的特点是:“读读共享”,“读写互斥”,“写写互斥”。(附:Lock取款机示例)

高性能缓存简易示例:

public classReadWriteMap {private final Mapmap;private final ReadWriteLock lock = newReentrantReadWriteLock();private final Lock readLock =lock.readLock();private final Lock writeLock =lock.writeLock();public ReadWriteMap(Mapmap) {this.map =map;

}publicObject put(Object key, Object value) {try{

writeLock.lock();returnmap.put(key, value);

}finally{

writeLock.unlock();

}

}publicObject get(Object key) {try{

readLock.lock();returnmap.get(key);

}finally{

writeLock.unlock();

}

}

}

3.Java中wait和sleep方法有什么区别。

sleep()是Thread类的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁(或监视器)依然保持。休眠时间结束后线程自动回到就绪状态。

wait()是Object类的方法,调用此方法会让当前线程暂停执行指定的时间,并放弃对象锁进入等待池(wait pool)。只有调用对象的notify()或notifyAll()方法才能唤醒等待池中的线程进入等锁池(lockpool)。如果线程重新获得对象的锁就可以进入就绪状态。

wait()方法多用于线程间通信,而sleep()只是在执行时暂停。

4.如何在Java中实现一个阻塞队列。

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。

1)阻塞的插入:当队列满时,队列会阻塞插入元素的线程,直到队列不满。

2)阻塞的移除:当队列空时,队列会阻塞移除元素的线程,直到队列不空。

public classBlockingQueue {private final List queue = new LinkedList<>();private int capacity = 10;publicBlockingQueue() {

}public BlockingQueue(intcapacity) {this.capacity =capacity;

}public synchronized Object put(Object item) throwsInterruptedException {while (queue.size() >=capacity) {

wait();

}

queue.add(item);

notifyAll();returnitem;

}public synchronized void remove() throwsInterruptedException {while (0 ==queue.size()) {

wait();

}

queue.remove(0);

notifyAll();

}public synchronized intgetSize() {returnqueue.size();

}

}

5.写一段死锁代码。说说你在Java中如何解决死锁。

6.Java中volatile关键字是什么。你如何使用它。它和Java中的同步方法有什么区别。

7.既然start()方法会调用run()方法,为什么我们调用 start() 方法,而不直接调用 run() 方法。

调用start()方法时,它会新建一个线程然后执行run()方法中的代码。

直接调用run()方法,则不会创建新线程,方法中的代码会在当前调用者的线程中执行。验证如下:

public static void main(String[] args) throwsInterruptedException {

Thread thread1= new Thread(() ->System.out.println(Thread.currentThread().getName()));

Thread thread2= new Thread(() ->System.out.println(Thread.currentThread().getName()));

thread1.setName("thread1");

thread1.start();

Thread.sleep(1000);

thread2.setName("thread2");

thread2.run();

}

8.什么是线程调度,Java中使用了什么线程调度方法。

线程调度是指系统为线程分配处理器使用权的过程,主要调度方式分两种,分别是协同式线程调度和抢占式线程调度。

协同式调度。线程执行时间由线程本身来控制,线程把自己的工作执行完之后,要主动通知系统切换到另外一个线程上。最大好处是实现简单,且切换操作对线程自己是可知的,没啥线程同步问题。坏处是线程执行时间不可控制,如果一个线程有问题,可能一直阻塞在那里。

抢占式调度。每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定(Java中,Thread.yield()可以让出执行时间,但无法获取执行时间)。线程执行时间系统可控,也不会有一个线程导致整个进程阻塞。

Java线程调度就是抢占式调度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值