首页 > 编程语言 >请编写一个程序,使用两个线程分别输出数字和字母,要求输出的结果为:1A2B3C4D5E6F7G8H9I10J。

请编写一个程序,使用两个线程分别输出数字和字母,要求输出的结果为:1A2B3C4D5E6F7G8H9I10J。

时间:2023-04-02 13:35:45浏览次数:32  
标签:count 输出 变量 lock 1A2B3C4D5E6F7G8H9I10J 计数器 线程

请编写一个程序,使用两个线程分别输出数字和字母,要求输出的结果为: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();
    }
}

代码执行流程如下:

  1. 程序启动后,创建了两个线程分别输出数字和字母。

  2. 两个线程都使用了同步块,并锁定了同一个静态的锁对象lock,以保证线程安全。

  3. 第一个线程进入循环后,判断计数器变量count是否小于等于10。由于count初始值为1,因此第一次进入循环。

  4. 第一个线程输出数字并将计数器变量加1。此时count变量为2。

  5. 第一个线程调用lock.notify()方法唤醒第二个线程,然后调用lock.wait()方法进入等待状态。

  6. 第二个线程被唤醒后,进入同步块,判断计数器变量count是否小于等于10。由于count变量为2,因此进入循环。

  7. 第二个线程输出字母并将计数器变量加1。此时count变量为3。

  8. 第二个线程调用lock.notify()方法唤醒第一个线程,然后调用lock.wait()方法进入等待状态。

  9. 第一个线程被唤醒后,进入同步块,判断 

  1. 计数器变量count此时为3,因此第一个线程进入循环,输出数字3并将计数器变量加1。此时count变量为4。

  2. 第一个线程调用lock.notify()方法唤醒第二个线程,然后调用lock.wait()方法进入等待状态。

  3. 第二个线程被唤醒后,进入同步块,判断计数器变量count是否小于等于10。由于count变量为4,因此进入循环。

  4. 第二个线程输出字母并将计数器变量加1。此时count变量为5。

  5. 第二个线程调用lock.notify()方法唤醒第一个线程,然后调用lock.wait()方法进入等待状态。

  6. 第一个线程被唤醒后,进入同步块,以此类推,直到循环输出数字和字母的次数都达到10次为止。

  7. 两个线程都执行完循环后,程序结束。

总体来说,这段代码的执行流程可以看作是两个线程交替输出数字和字母,直到循环次数达到10次为止。其中,使用了同步块和锁对象来保证线程安全,使用wait()notify()方法来实现线程之间的通信。

标签:count,输出,变量,lock,1A2B3C4D5E6F7G8H9I10J,计数器,线程
From: https://www.cnblogs.com/dk1024/p/17280305.html

相关文章

  • Golang 需要至少 5 个操作系统线程
    Golang需要至少5个操作系统线程主线程:Golang代码执行的入口点,负责初始化程序,并启动其他Goroutine。垃圾回收器线程:Golang内置了垃圾回收器,使用专门的线程来执行垃圾回收操作,回收不再使用的内存空间。CPU核心数个系统线程:每个核心需要一个系统线程来支持并发任务的执行......
  • 线程相关
    个人理解,如有错误,请海涵多任务调度大部分操作系统如Linux、Windos等,都是采用时间片轮转的抢占式调度方式来实现任务调度的。在这种调度方式下,每个进程执行一个任务都会在一短时间后暂停执行,切换其他进程执行任务。由于进程的上下文切换,CPU需要耗费大量的时间来保存该进程的内存......
  • NonBlocking 非阻塞IO 状态下的实现单线程协程socket通信
    #服务器端#-*-coding:utf-8-*-importtimefromsocketimport*server=socket(AF_INET,SOCK_STREAM)server.bind(('127.0.0.1',8081))server.listen(5)server.setblocking(False)#至关重要的一步!!!conn_l=[]print('waiting...')whileTrue:......
  • 第2章 线程同步精要
    第2章线程同步精要线程同步的四项原则,按重要性排列:1.首要原则是尽量最低限度地共享对象,减少需要同步的场合。一个对象能不暴露给别的线程就不要暴露;如果要暴露,优先设置对象不可更改;实在不行才暴露可修改的对象,并用同步措施来充分保护它。2.其次是使用高级的并发编程构件,如TaskQ......
  • 实现Callable接口创建线程
    ​ 通过实现Callable接口创建线程与实现Runnable接口创建线程类似,不同之处在于Callable的call()方法可以返回一个结果,并且可以抛出异常。以下是通过实现Callable接口创建线程的示例代码:importjava.util.concurrent.Callable;publicclassMyCallableimplementsCallable<Str......
  • 通过线程池的方式获取线程
    ​ 使用线程池可以更好地管理线程的数量,避免线程数量过多导致系统性能下降的问题。Java中提供了Executor框架,可以很方便地创建和管理线程池。以下是使用线程池的示例代码:importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassMa......
  • Java创建线程的三种方式
    创建线程的三种方式1.继承Thread类,重写run方法publicclassMyThreadextendsThread{publicvoidrun(){System.out.println("HellofromMyThread!");}}publicclassMain{publicstaticvoidmain(String[]args){MyThreadthread......
  • Java线程:wait()和notify()
    一、wait()和notify()含义二、标准代码示例创建两个线程Thread0和Thread1。代码实现:运行流程详解三、什么时候释放锁—wait()、notify()四、用生活故事讲懂线程的等待唤醒1.老王和老李(专家程序员):2.王哥和李哥(普通程序员):3.小王和小李(新手程序员):五、问题理解1、执行wait()的......
  • 多线程
    内容什么是线程如何创建线程线程的调度线程的一个设计模式:生产消费者模型线程池线程集合对象(侧重点)一、什么是线程进程:运行中的程序才可以称为进程,一个程序一个进程。宏观并行,微观串行。线程:1.任何一个程序都至少拥有一个线程,即主线程。但是java程序默认有两个线......
  • C# 直接在子线程中对窗体上的控件操作是会出现异常
    https://www.bbsmax.com/A/MAzA8klpd9/ Form1里privatedelegatevoidDispMSGDelegate(intindex,stringMSG);publicvoidDispMsg(intiIndex,stringstrMsg){if(this.richTextBox1.InvokeRequired==false)......