6
回答
Java多线程顺序有序执行
华为云4核8G,高性能云服务器,免费试用   
package coderr.kerwin.codetest.test;

public class Test {
	
	public static void main(String[] args) throws InterruptedException {		
		TempObject obj1 = new TempObject(1,5);
		TempObject obj2 = new TempObject(2,5);
		TempObject obj3 = new TempObject(3,5);
		new Thread(new SelfRunnable3(obj3, obj1)).start();
		Thread.sleep(100);
		new Thread(new SelfRunnable3(obj1, obj2)).start();
		Thread.sleep(100);
		new Thread(new SelfRunnable3(obj2, obj3)).start();
		Thread.sleep(100);
	}
	
	static class SelfRunnable3 implements Runnable {
		
		private TempObject prev;
		private TempObject self;
		private static int num = 1;
		
		public SelfRunnable3(TempObject prev, TempObject self) {
			this.prev = prev;
			this.self = self;
		}
		
		@Override
		public void run() {
			while (num <= 75) {
				System.out.println("p:"+prev.getId()+";s:"+self.getId()+";p-"+num);
				synchronized (prev) {
					System.out.println("p:"+prev.getId()+";s:"+self.getId()+";s-"+num);
					synchronized (self) {
						self.notify();
						self.print(num);
						num+=self.getCount();
					}
					try {
						prev.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
	}
	
	static class TempObject {
		
		private int id;
		private int count;
		
		public TempObject(int id, int count) {
			super();
			this.id = id;
			this.count = count;
		}
		
		public int getId() {
			return id;
		}

		public void setId(int id) {
			this.id = id;
		}

		public int getCount() {
			return count;
		}

		public void setCount(int count) {
			this.count = count;
		}

		public synchronized void print(int num) {
			for (int i = 0; i < count; i++) {
				System.out.println("Thread " + id + ":" + num++);
			}
		}
		
	}
	
}

一道面试题、同时开启三个线程A/B/C,A线程打印1,2,3,4,5;B线程打印6,7,8,9,10;C线程打印11,12,13,14,15;然后A线程继续打印16,17,18,19,20。。。。最后直到线程C打印71,72,73,74,75程序结束。。。如上代码已经实现了本题所要的效果、但是为什么最终程序打印到75后并没有结束、貌似出现了死锁。请问问题在哪里呢?求大神指教!!!!我调试看了下、貌似只有线程A顺利结束了。线程B和线程C并没有结束。



举报
ileler
发帖于3年前 6回/5K+阅
共有6个答案 最后回答: 3年前

引用来自“铂金渣男”的评论

这个程序同一时间只有一个在执行,另两个在等待。所以在最后的阶段,C线程执行的时候 A,B都在等待,C执行notify的时候会唤醒A的等待,因此,A会执行,但是这个时候C已经把num赋值成了75,A执行num <=75的时候不满足,因此A线程整个结束了。C执行完了会执行obj2.wait();而obj2的唤醒需要B线程执行obj2.notify()。B线程现在一直在等待,需要A线程执行obj1.notify()才会继续执行,但是A已经结束了,因此B无限等待,C无限等待
把run方法改成下面就可以了
public void run() {
            while (num <= 75) {
                System.out.println("p:"+prev.getId()+";s:"+self.getId()+";p-"+num);
                synchronized (prev) {
                    System.out.println("p:"+prev.getId()+";s:"+self.getId()+";s-"+num);
                    synchronized (self) {
                        self.notify();
                        self.print(num);
                        num+=self.getCount();
                    }
                    try {
                        prev.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            
            synchronized(self){
            	self.notify();
            }
        }



--- 共有 2 条评论 ---
alexwan为什么输出的最后一个值 有时 是80 有时是75 3年前 回复
ileler牛逼。真的可以了。。但是还是没搞懂这是为啥???为啥在while结束后锁住self然后又notify()??????大神抽空给讲解下可好? 3年前 回复
这个程序同一时间只有一个在执行,另两个在等待。所以在最后的阶段,C线程执行的时候 A,B都在等待,C执行notify的时候会唤醒A的等待,因此,A会执行,但是这个时候C已经把num赋值成了75,A执行num <=75的时候不满足,因此A线程整个结束了。C执行完了会执行obj2.wait();而obj2的唤醒需要B线程执行obj2.notify()。B线程现在一直在等待,需要A线程执行obj1.notify()才会继续执行,但是A已经结束了,因此B无限等待,C无限等待
--- 共有 1 条评论 ---
ileler兄弟、那能给个解决方案吗???整了半天还是不行! 3年前 回复

http://blog.csdn.net/zyplus/article/details/6672775

楼主可以去看看这个

--- 共有 2 条评论 ---
alexwan这个博主写的有问题 3年前 回复
ileler我就是照着这个才写出来的。。。。发现虽然执行出了想要的结果。但是有线程死锁! 3年前 回复
public class T {

	public static void main(String[] args) throws InterruptedException {        
        TempObject obj1 = new TempObject(1,5);
        TempObject obj2 = new TempObject(2,5);
        TempObject obj3 = new TempObject(3,5);
        new Thread(new SelfRunnable3(obj1, obj2)).start();
        Thread.sleep(100);
        new Thread(new SelfRunnable3(obj2, obj3)).start();
        Thread.sleep(100);
        new Thread(new SelfRunnable3(obj3, obj1)).start();
        Thread.sleep(100);
    }
     
    static class SelfRunnable3 implements Runnable {
         
        private TempObject self;//当前
        private TempObject successor;//后继
        private static int num = 1;
         
        public SelfRunnable3(TempObject self,TempObject successor) {
            this.successor = successor;
            this.self = self;
        }
         
        @Override
        public void run() {
            while (num <= 75) {
            		System.out.println("当前:"+self.getId()+"-----------------------"+"后继:"+successor.getId());
            		
            		synchronized (self) {
            			self.print(num);
    					num += self.getCount();
    					synchronized (successor) {
                			successor.notify();
    					}
    					try {
							self.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
    				}
            }
            synchronized (successor) {
            	successor.notify();
            }
            
        }
        
    }
     
    static class TempObject {
         
        private int id;
        private int count;
         
        public TempObject(int id, int count) {
            super();
            this.id = id;
            this.count = count;
        }
         
        public int getId() {
            return id;
        }
 
        public void setId(int id) {
            this.id = id;
        }
 
        public int getCount() {
            return count;
        }
 
        public void setCount(int count) {
            this.count = count;
        }
 
        public synchronized void print(int num) {
            for (int i = 0; i < count; i++) {
                System.out.println("Thread " + id + ":" + num++);
            }
            
        }
         
    }

}



顶部