为什么要在RUN方法中调用Sleep

本文探讨了在线程中使用sleep方法的原因,并分析了在单窗口或多窗口售票系统中线程同步的重要性。对于多线程操作同一资源的情况,文章强调了使用线程同步避免数据失真的必要性。
一般在线程的run方法里调用sleep方法是为了让当前线程暂停执行,以给其他线程执行的机会,其实这里有个问题,到底是单窗口售票还是多窗口,如果是单窗口,那么买票的线程是多个,售票的线程是一个,买票的线程应该处在一个队列之中,买票的线程只负责获得票,具体操作资源的线程是售票线程,只有它一个线程的话并不会出现线程同步问题吧;但如果是多个售票线程的话,这时候就有必要使用线程同步了,因为多个线程对同一个资源进行修改很有可能造成数据最后失真的问题,同时这个时候的sleep方法也是很有必要的,现实中的售票员也必须休息才能工作的阿
在JUnit测试中调用线程的`start()`方法时,`run()`方法没有执行的原因主要与JUnit测试框架的设计机制有关。JUnit测试框架默认情况下不会等待线程完成执行,而是继续执行后续的测试逻辑,甚至在测试方法执行完毕后直接结束整个测试进程。这意味着如果线程的执行时间较长,或者依赖于主线程的某些同步操作,线程可能在尚未完成执行时就被提前终止。 具体来说,JUnit测试框架的`TestRunner`在执行测试方法时,并不会主动跟踪或等待任何新启动的线程。一旦测试方法执行完成,`TestRunner`会调用`System.exit()`方法结束当前JVM进程,这会导致所有未完成的线程被强制终止,即使它们尚未执行完毕。例如,在测试方法中启动一个线程并调用`start()`方法后,主线程可能已经完成执行并退出,而子线程还没有来得及执行`run()`方法中的逻辑,或者仅执行了一部分[^3]。 此外,JUnit测试框架本身不支持守护线程(Daemon Thread),这意味着即使将线程设置为守护线程,也不会改变JUnit测试框架在主线程结束后立即退出的行为。通常情况下,Java的主线程(即`main`方法)并不是一个守护线程,而是一个用户线程。当所有用户线程都结束时,JVM才会退出。然而,JUnit测试框架在测试方法执行完毕后会主动调用`System.exit()`,这会绕过正常的线程生命周期管理,导致非守护线程被强制终止[^1]。 为了验证线程是否成功执行了`run()`方法,可以通过`Thread.sleep()`方法让主线程等待一段时间,以确保子线程有机会完成执行。例如: ```java @Test public void testThreadExecution() { Thread thread = new Thread(() -> { System.out.println("子线程执行"); }); thread.start(); try { Thread.sleep(2000); // 等待2秒确保子线程执行完毕 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主线程结束"); } ``` 上述代码通过`Thread.sleep()`人为地延长主线程的执行时间,确保子线程有机会执行其`run()`方法中的逻辑。然而,这种方法并不适用于所有场景,尤其是在需要精确控制线程执行顺序或多线程协同工作的测试中。 更可靠的解决方案是使用`CountDownLatch`或`CyclicBarrier`等并发工具来实现线程间的同步。例如,使用`CountDownLatch`可以让主线程等待子线程完成后再继续执行: ```java @Test public void testThreadWithCountDownLatch() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); Thread thread = new Thread(() -> { System.out.println("子线程执行"); latch.countDown(); // 通知主线程可以继续执行 }); thread.start(); latch.await(); // 等待子线程完成 System.out.println("主线程结束"); } ``` 通过这种方式,可以确保主线程在子线程完成执行后再继续执行,从而避免因JUnit测试框架提前退出而导致的线程未执行问题。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值