Java多线程-线程安全问题练习题
在这个关于Java多线程的练习中,我们将探讨线程安全问题在实际编程中的应用,特别是当涉及到共享资源和同步时。首先,我们来看第一个练习题——新年倒计时模拟。
**练习题1:新年倒计时**
题目要求编写一个程序,模拟新年倒计时,每秒输出一个数字从10到1,最后输出“新年快乐”。由于题目未明确要求使用多线程,我们可以直接在主线程中实现。代码中,`Thread.sleep(1000)`用于模拟一秒的暂停,但是需要注意的是,`Thread.sleep()`会抛出`InterruptedException`,这是一种编译时异常,因此我们需要用`try-catch`块来捕获并处理它,确保程序不会因异常而中断。
```java
public class HappyNewYear {
public static void main(String[] args) {
for (int i = 10; i >= 1; i--) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
System.out.println("新年快乐!");
}
}
```
第二个练习题涉及到了`Thread.sleep()`方法及其对线程执行的影响。问题在于,当代码执行`Thread.sleep()`后,可能会让人疑惑哪个线程进入了阻塞状态。实际上,`Thread.sleep()`会让当前执行的线程进入睡眠状态,而不是整个程序或另一个线程。在提供的代码示例中,只有一个线程在运行,因此调用`sleep()`后,这个线程会进入阻塞状态,直到被唤醒。
```java
public class ThreadTest {
public static void main(String[] args) {
int i = 0;
new Thread(() -> {
if (i > 0) {
System.out.println(i);
} else {
System.out.println("HappyNewYear!");
}
}).start();
// 当主线程执行到这里,新线程会开始执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
```
在这个例子中,当`Thread.sleep()`结束后,新线程会继续执行,因为它已经在主线程启动后开始工作。所以,尽管`sleep()`方法阻塞了主线程,但线程的执行顺序仍然保持在新线程之后。
总结这两个练习题,它们分别展示了如何在主线程中进行简单的定时操作和理解`Thread.sleep()`对单线程执行的影响。通过这些实践,你可以更深入地理解Java多线程中的基本概念,包括主线程、线程同步以及如何避免线程安全问题。在多线程编程中,了解何时需要使用锁、synchronized关键字以及原子操作等工具来保护共享资源至关重要,这有助于编写出健壮且高效的并发代码。