请编写一个程序,使用两个线程分别输出数字和字母,要求输出的结果为:1A2B3C4D5E6F7G8H9I10J。
提示:可以使用Java中的wait()和notify()方法来实现线程间的通信。
public class NumberLetterPrinter { // 定义一个静态的锁对象 private static final Object lock = new Object(); // 定义一个计数器变量 private static volatile int count = 1; public static void main(String[] args) { // 创建第一个线程,输出数字 new Thread(() -> { // 使用同步块,锁定锁对象 synchronized (lock) { // 当计数器变量小于等于10时,一直循环输出数字 while (count <= 10) { // 输出数字并将计数器变量加1 System.out.print(count++); try { // 唤醒另一个线程并进入等待状态 lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 退出循环后,释放锁对象 lock.notify(); } }).start(); // 创建第二个线程,输出字母 new Thread(() -> { // 使用同步块,锁定锁对象 synchronized (lock) { // 当计数器变量小于等于10时,一直循环输出字母 while (count <= 10) { // 输出字母并将计数器变量加1 System.out.print((char) (count + 64)); try { // 唤醒另一个线程并进入等待状态 lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 退出循环后,释放锁对象 lock.notify(); } }).start(); } }
代码执行流程如下:
-
程序启动后,创建了两个线程分别输出数字和字母。
-
两个线程都使用了同步块,并锁定了同一个静态的锁对象
lock
,以保证线程安全。 -
第一个线程进入循环后,判断计数器变量
count
是否小于等于10。由于count
初始值为1,因此第一次进入循环。 -
第一个线程输出数字并将计数器变量加1。此时
count
变量为2。 -
第一个线程调用
lock.notify()
方法唤醒第二个线程,然后调用lock.wait()
方法进入等待状态。 -
第二个线程被唤醒后,进入同步块,判断计数器变量
count
是否小于等于10。由于count
变量为2,因此进入循环。 -
第二个线程输出字母并将计数器变量加1。此时
count
变量为3。 -
第二个线程调用
lock.notify()
方法唤醒第一个线程,然后调用lock.wait()
方法进入等待状态。 -
第一个线程被唤醒后,进入同步块,判断
-
计数器变量
count
此时为3,因此第一个线程进入循环,输出数字3并将计数器变量加1。此时count
变量为4。 -
第一个线程调用
lock.notify()
方法唤醒第二个线程,然后调用lock.wait()
方法进入等待状态。 -
第二个线程被唤醒后,进入同步块,判断计数器变量
count
是否小于等于10。由于count
变量为4,因此进入循环。 -
第二个线程输出字母并将计数器变量加1。此时
count
变量为5。 -
第二个线程调用
lock.notify()
方法唤醒第一个线程,然后调用lock.wait()
方法进入等待状态。 -
第一个线程被唤醒后,进入同步块,以此类推,直到循环输出数字和字母的次数都达到10次为止。
-
两个线程都执行完循环后,程序结束。
总体来说,这段代码的执行流程可以看作是两个线程交替输出数字和字母,直到循环次数达到10次为止。其中,使用了同步块和锁对象来保证线程安全,使用wait()
和notify()
方法来实现线程之间的通信。