首页 > 代码库 > java线程 - 线程唤醒后并被执行时,是在上次阻塞的代码行重新往下执行,而不是从头开始执行
java线程 - 线程唤醒后并被执行时,是在上次阻塞的代码行重新往下执行,而不是从头开始执行
今天重新把昨晚的线程同步面试题做一遍时,发现实际情况运行下来时,线程一直不同步。后来经过不断测试,发现自己的一个误区。
之前一直以为,线程如果被唤醒后再次执行时,会从头开始运行这个线程,也就是重新运行Runnable中的run()方法;
而实际情况是,被唤醒并且被执行的线程是从上次阻塞的位置从下开始运行,也就是从wait()方法后开始执行。
所以判断是否进入某一线程的条件 是用while判断,而不是用If判断判断。
下面举例说明:
如果三个线程同步工作,第一个线程打印1,2,3,4,5 ,然后第二个线程打印1,2,3,4,5 ,接着第三个线程也打印 1,2,3,4,5,重复100次。
1 public class Thread_test { 2 3 static final manage m = new manage(); 4 5 public static void main(String[] args) { 6 //线程一 7 new Thread(new Runnable() { 8 @Override 9 public void run() {10 // TODO Auto-generated method stub11 for(int i=0;i<50;i++){12 m.threadPrint(i,0);13 }14 }15 }).start();16 17 //线程二18 new Thread(new Runnable(){19 20 public void run(){21 for(int i=0;i<50;i++){22 m.threadPrint(i,1);23 }24 }25 }).start();26 27 //线程三28 new Thread(new Runnable(){29 30 public void run(){31 for(int i=0;i<50;i++){32 m.threadPrint(i,2);33 }34 }35 }).start();36 37 }38 39 }40 41 42 //控制线程执行的顺序43 class manage{44 //权限,0代表1号线程执行,1代表二号线程执行,2代表三号线程执行45 private int isA = 0;46 47 public synchronized void threadPrint(int i,int n){48 /*该处应用while来判断是否轮到该线程执行,假如用If判断的话,如果该线程阻塞后再次被唤醒执行时(其他线程调用this.notifyAll()),
他会从this.wait()后面的代码开始执行,即时没轮到该线程执行*/49 while(this.isA != n){50 try {
this.wait();53 } catch (Exception e) {54 // TODO: handle exception55 }56 }57 for(int j=0;j<5;j++){58 System.out.println(Thread.currentThread().getName()+":"+(j+1)+" loop in "+(i+1));59 }60 this.isA = (this.isA+1)%3;//将权限传递给后一个进程62 this.notifyAll();63 }64 65 66 67 }
java线程 - 线程唤醒后并被执行时,是在上次阻塞的代码行重新往下执行,而不是从头开始执行
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。