网站没备案或与实际备案不符,品牌网站建设策,wordpress七牛云插件,做销售在哪个网站找客户最近面试遇到的一道题#xff0c;需要三个线程交替打印0-100#xff0c;当时对多线程并不是很熟悉因此没怎么写出来#xff0c;网上搜了之后得到现
synchronized wait/notifyAll
实现思路#xff1a;判断当前打印数字和线程数的取余#xff0c;不等于当前线程则处于等待…最近面试遇到的一道题需要三个线程交替打印0-100当时对多线程并不是很熟悉因此没怎么写出来网上搜了之后得到现
synchronized wait/notifyAll
实现思路判断当前打印数字和线程数的取余不等于当前线程则处于等待状态。循环结束唤醒所有等待线程。
public class PrintExample {//创建一个公共锁对象private static final Object Lock new Object();//执行线程数private static final int THREAD_COUNT 3;//打印数字的起始点private static volatile int START 0;//打印数字的结束点private static final int END 100;private static class Print implements Runnable{private final int index;public Print(int index){this.index index;}Overridepublic void run() {while(STARTEND){synchronized (Lock){//START和线程数进行取余如果不等于当前线程的则等待while(START % THREAD_COUNT ! index){try{Lock.wait();}catch (Exception e){e.printStackTrace();}}//否则进行输出if(STARTEND){System.out.println(Thread (index1) ,打印结果 START);}START;//唤醒等待线程Lock.notifyAll();}}}public static void main(String[] args) {for(int i 0; i THREAD_COUNT; i){new Thread(new Print(i)).start();}}}
}ReetrantLock await/signalAll
实现思路实现方式和synchronized wait/notifyAll儿乎完全一样。我们只需要4步 1.synchronized 替换为ReentrantLock
2.根据锁对象创建一个Condition对象
3.wait替换成await
4.notifyAll 替换为 signalAll
public class PrintExample {//创建一个公共锁对象private static final ReentrantLock Lock new ReentrantLock();//根据锁对象创建一个Condition对象private static final Condition CONDITION Lock.newCondition();//执行线程数private static final int THREAD_COUNT 3;//打印数字的起始点private static volatile int START 0;//打印数字的结束点private static final int END 100;private static class Print implements Runnable{private final int index;public Print(int index){this.index index;}Overridepublic void run() {while(STARTEND){Lock.lock();try {//START和线程数进行取余如果不等于当前线程的则等待while(START % THREAD_COUNT ! index){try{CONDITION.await();}catch (Exception e){e.printStackTrace();}}//否则进行输出if(STARTEND){System.out.println(Thread (index1) ,打印结果 START);}START;//唤醒等待线程CONDITION.signalAll();}catch (Exception e){e.printStackTrace();}finally {Lock.unlock();}}}public static void main(String[] args) {for(int i 0; i THREAD_COUNT; i){new Thread(new Print(i)).start();}}}
}ReetrantLock await/signal
因为Condition相对wait/notify方式可以唤醒指定线程。那我们就完全不用每次都唤醒全部线程仅需要唤醒下一次需要执行的线程就可以了。 相比较 ReentrantLock await/signalAll 改进方法 1.去除公共的Condition对象替换为ListCondition conditions 2.调用下一个线程的Condition对象的signal方法唤醒下一个线程
public class PrintExample {//创建一个公共锁对象private static final ReentrantLock Lock new ReentrantLock();//根据锁对象创建一个Condition对象//private static final Condition CONDITION Lock.newCondition();//执行线程数private static final int THREAD_COUNT 3;//打印数字的起始点private static volatile int START 0;//打印数字的结束点private static final int END 100;private static class Print implements Runnable{private final int index;private final ListCondition conditions;public Print(int index,ListCondition conditions){this.index index;this.conditions conditions;}//只唤醒下一个线程private void signalNext(){int nextIndex (index 1) % THREAD_COUNT;conditions.get(nextIndex).signal();}Overridepublic void run() {while(STARTEND){Lock.lock();try {//START和线程数进行取余如果不等于当前线程的则等待while(START % THREAD_COUNT ! index){try{conditions.get(index).await();}catch (Exception e){e.printStackTrace();}}//否则进行输出if(STARTEND){System.out.println(Thread (index1) ,打印结果 START);}START;//唤醒等待线程signalNext();}catch (Exception e){e.printStackTrace();}finally {Lock.unlock();}}}public static void main(String[] args) {ListCondition conditionList new ArrayList();conditionList.add(Lock.newCondition());conditionList.add(Lock.newCondition());conditionList.add(Lock.newCondition());for(int i 0; i THREAD_COUNT; i){new Thread(new Print(i,conditionList)).start();}}}
}此处使用 ListCondition conditions让每个线程都拥有属于自己的condition这样可以单独唤醒和等待。 Condition是什么
概念
condition可以理解为条件队列。当一个线程在调用了其await方法以后直到线程等待的某个条件为真的时候才会被唤醒。Condition必须要配合锁一起使用因为对共享状态变量的访问发生在多线程环境下。一个Condition的实例必须与一个Lock绑定因此Condition一般都是作为Lock的内部实现
方法
Condition依赖于Lock接口
方法解释lock.newCondition()生成一个Conditionawait()对应Object的wait()使线程等待signal()对应Object的notify()唤醒线程
注意调用Condition的await()和signal()方法都必须在lock.lock()和lock.unlock()之间使用
在生产者和消费者中Condition的执行方式
当在线程Consumer中调用await方法后线程Consumer将释放锁并且将自己沉睡等待唤醒。这时等到线程Producer获取到锁后开始执行任务完毕后调用Condition的signalall方法唤醒线程Consumer线程Consumer恢复执行。
以上说明Condition是一个多线程间协调通信的工具类使得某个或某些线程一起等待某个条件Condition,只有当该条件具备( signal 或者 signalAll方法被带调用)时 这些等待线程才会被唤醒从而重新争夺锁