这是一道考察多线程的题目。应题目的要求,子线程循环10次和主线程循环100次的中途不能被打断,则须要在循环方法里面加入互斥锁。要连续有规律运行主线程和子线程,能够考虑当线程执行完一个周期的循环后,让线程休眠让出线程运行权,或者使用wita()和notify()方法。java
public class TranditionThreadCommunication { public static void main(String[] args) { final Business business = new Business(); // 子线程循环 new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 50; i++) { try { business.sub(i); } catch (InterruptedException e) { } } } }).start(); // 主线程循环 for (int i = 1; i <= 50; i++) { try { business.mian(i); } catch (InterruptedException e) { } } } } /** * 业务类型(包含各色的同步锁) */ class Business { // sub()方法是否该运行标识 private boolean bShouldSub = true; /** * 循环100次打印的方法sub() * * @param i * @throws InterruptedException */ public synchronized void sub(int i) throws InterruptedException { while (!bShouldSub) { // 当 bShouldSub 为 false 时,则等待 this.wait(); } for (int j = 1; j <= 10; j++) { System.out.println("sub thread : 第" + i + "行, 第" + j + "列"); } bShouldSub = false; // 执行for循环后,标志sub()方法不可再执行 this.notify(); // 唤醒线程 } /** * 循环100次打印的方法mian() * * @param i * @throws InterruptedException */ public synchronized void mian(int i) throws InterruptedException { while (bShouldSub) { this.wait(); } for (int j = 1; j <= 100; j++) { System.out.println("main thread : 第" + i + "行, 第" + j + "列"); } bShouldSub = true; // 执行for循环后,标志sub()方法可再执行了 this.notify(); // 唤醒线程 } }
(1)要用到共同数据(包括同步锁)或共同算法的若干个方法应该归在同一个类身上,这种设计体现了高类聚和程序的健壮性。像上面的循环10次和循环100次的操做都须要用到锁时,能够将这两个方法加上锁(synchronized)并放到Business类中。算法
(2)上面答案中的多线程
while (bShouldSub) { this.wait(); }
借鉴了javaAPI 中的wait()方法的写法,主要是为了防止线程之间可能出现的伪唤醒。app
java API 中的wait()方法的原文以下:ide
public final void wait() throws InterruptedException 在其余线程调用此对象的 notify() 方法或 notifyAll() 方法前,致使当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用同样。 当前线程必须拥有此对象监视器。该线程发布对此监视器的全部权并等待,直到其余线程经过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。而后该线程将等到从新得到对监视器的全部权后才能继续执行。this
对于某一个参数的版本,实现中断和虚假唤醒是可能的,并且此方法应始终在循环中使用:线程
synchronized (obj) { while (<condition does not hold>) obj.wait(); // Perform action appropriate to condition }
此方法只应由做为此对象监视器的全部者的线程来调用。有关线程可以成为监视器全部者的方法的描述,请参阅 notify 方法。 抛出: IllegalMonitorStateException - 若是当前线程不是此对象监视器的全部者。 InterruptedException - 若是在当前线程等待通知以前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。设计