现在有T1、T2、T3三个线程,你怎样保证T2在T1执⾏完后执⾏,T3在T2执⾏完后执⾏?
⽬的是检测你对”join”⽅法是否熟悉。这个多线程问题⽐较简单,可以⽤join⽅法实现。核⼼:
thread.Join把指定的线程加⼊到当前线程,可以将两个交替执⾏的线程合并为顺序执⾏的线程。 ⽐如在线程B中调⽤了线程A的Join()⽅法,直到线程A执⾏完毕后,才会继续执⾏线程B。 想要更深⼊了解,建议看⼀下join的源码,也很简单的,使⽤wait⽅法实现的。t.join(); //调⽤join⽅法,等待线程t执⾏完毕
t.join(1000); //等待 t 线程,等待时间是1000毫秒。
public static void main(String[] args) { method01(); method02(); }
/**
* 第⼀种实现⽅式,顺序写死在线程代码的内部了,有时候不⽅便 */
private static void method01() {
Thread t1 = new Thread(new Runnable() { @Override public void run() {
System.out.println(\"t1 is finished\"); } });
Thread t2 = new Thread(new Runnable() { @Override public void run() { try {
t1.join();
} catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(\"t2 is finished\"); } });
Thread t3 = new Thread(new Runnable() { @Override public void run() { try {
t2.join();
} catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(\"t3 is finished\"); } });
t3.start(); t2.start(); t1.start(); }
/**
* 第⼆种实现⽅式,线程执⾏顺序可以在⽅法中调换 */
private static void method02(){
Runnable runnable = new Runnable() { @Override public void run() {
System.out.println(Thread.currentThread().getName() + \"执⾏完成\"); } };
Thread t1 = new Thread(runnable, \"t1\"); Thread t2 = new Thread(runnable, \"t2\"); Thread t3 = new Thread(runnable, \"t3\"); try {
t1.start(); t1.join(); t2.start(); t2.join(); t3.start(); t3.join();
} catch (InterruptedException e) { e.printStackTrace(); } }
在Java中Lock接⼝⽐synchronized块的优势是什么?你需要实现⼀个⾼效的缓存,它允许多个⽤户读,但只允许⼀个⽤户写,以此来保持它的完整性,你会怎样去实现它?
Lock读写锁机制可以实现!
在Java中Lock接⼝⽐synchronized块的优势是什么? Lock接⼝最⼤的优势是为读和写分别提供了锁。
import java.text.SimpleDateFormat;import java.util.Date;import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class JoinTest2 {
public static void main(String[] args) { final TheData theData = new TheData(); for(int i=0;i<4;i++){
new Thread(new Runnable() { @Override
public void run() { theData.get(); }
}).start(); }
for(int i=0;i<4;i++){
new Thread(new Runnable() { @Override
public void run() {
theData.put(new Random().nextInt(1000)); }
}).start(); } } }
class TheData{
private Integer data = 0;
private ReadWriteLock rwLock = new ReentrantReadWriteLock();
SimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd hh:mm:ss\"); public void get(){
rwLock.readLock().lock();//读锁开启,读进程均可进⼊ try{//⽤try finally来防⽌因异常⽽造成的死锁
System.out.println(Thread.currentThread().getName()+\"read lock is ready..\"+sdf.format(new Date())); Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+\"read data is\"+data); }catch (InterruptedException e) { e.printStackTrace(); }finally{
rwLock.readLock().unlock();//读锁解锁 } }
public void put(Integer data){
rwLock.writeLock().lock();//写锁开启,这时只有⼀个写线程进⼊ try{//⽤try finally来防⽌因异常⽽造成的死锁
System.out.println(Thread.currentThread().getName()+\"write lock is ready..\"+sdf.format(new Date())); Thread.sleep(1000); this.data = data;
System.out.println(Thread.currentThread().getName()+\"write data is\"+data); }catch (InterruptedException e) { e.printStackTrace(); }finally{
rwLock.writeLock().unlock();//写锁解锁 } }}
在java中wait和sleep⽅法的不同?
通常会在电话⾯试中经常被问到的Java线程⾯试问题。
最⼤的不同是在等待时wait会释放锁,⽽sleep⼀直持有锁。Wait通常被⽤于线程间交互,sleep通常被⽤于暂停执⾏。
此处我想理⼀下Java多线程的基础知识:
- Java的多线程锁是挂在对象上的,并不是在⽅法上的。即每个对象都有⼀个锁,当遇到类似synchronized的同步需要时,就会监视(monitor)每个想使⽤本对象的线程按照⼀定的规则来访问,规则也就是在同⼀时间内只能有⼀个线程能访问此对象。
- Java中获取锁的单位是线程。当线程A获取了对象B的锁,也就是对象B的持有标记上写的是线程A的唯⼀标识,在需要同步的情况下的话,只有线程A能访问对象B。
- Thread常⽤⽅法有:start/stop/yield/sleep/interrupt/join等,他们是线程级别的⽅法,所以并不会太关⼼锁的具体逻辑。
- Object的线程有关⽅法是:wait/wait(事件参数)/notify/notifyAll,他们是对象的⽅法,所以使⽤的时候就有点憋屈了,必须当前线程获取了本对象的锁才能使⽤,否则会报异常。但他们能更细粒度的控制锁,可以释放锁。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- banwoyixia.com 版权所有 湘ICP备2023022004号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务