StartMain Startl EndMain End1 Start2 Error End2 画个时序图,并发问题。Main线程调用delay并不影响前面启动的线程,他们是并发关系注意一点,interrupt会抛一个中断异常,因此会有error打印其他没什么好分析的

解决方案 »

  1.   

    输出结果:
    StartMain Startl  EndMain End1 Start2  Error End2 分析:
    首先是main方法运行,输出StartMain,接着是t1.start(),输出Startl,之后t1 执行sleep,因此main方法继续运行,t2启动,因为t1,t2共享resource资源,在t1之行结束释放该资源之前,t2无法执行,因此main方法继续执行输出EndMain ,时间到,t1执行,输出End1,t1释放资源后t2执行,输出Start2  Error End2 
      

  2.   

    运行结果:
    StartMain Startl EndMain End1 Start2 Error End2执行过程:程序从main()方法开始执行,打印出StartMain,接着Thread1的线程对象开启,去执行run()方法,因为对resource加了锁,因此在次线程未结熟之前其他线程不能执行,因为resource还没有被释放;Thread1的线程对象输出Start1,然后调用了delay()方法,睡眠了6秒钟,在睡眠期间锁依然起作用,而且程序的主方法依然在执行,所以先输出EndMain,然后Thread1的线程对象睡眠时间够了,继续执行,输出End1;
    此时t2已经启动,等待resource被释放执行自己的run()方法;t2首先打印出Start2,接着调用delay()方法,睡眠2秒钟,再次期间主方法继续执行,执行interrupt()方法时会抛出InterruptedException异常,所以会执行catch()语句块的内容,即输出Error,最后输出End2。
    以上就是这个程序的完整执行过程,你应该能看懂,仔细分析是关键。
      

  3.   

    1.T1和T2使用相同的同步字段resource,所以一个运行时另一个需要等待其运行成功。
    2.delay方法沉睡的是调用它的线程,所以线程代码执行后会处于沉睡状态。
    3.interrupt方法,根据JDK的文档描述,该方法名称虽然叫中断,但是他并不是终止线程运行,而是提供标记功能,程序员根据读取该标记状态编写中断代码,但是当线程处于wait,sleep,IO阻塞中时会退出阻塞并抛出异常,对于不处于上述状态的线程仅修改中断状态而不抛出异常(注意该处不会对线程有其他操作,仅仅会修改中断属性为true)。
    4.在线程1退出前,线程2始终处于阻塞状态,而线程1沉睡了6秒才执行完毕所以线程2也被阻塞了6秒。6秒后主线程与线程1相继执行完毕,此时线程2才开始执行,在执行到sleep代码是,该方法检测到该线程已经设置了中断标记,所以报出InterruptException。