当前位置: 首页 > 知识库问答 >
问题:

连续执行线程以打印1A 2B 3C 4D

汪胡非
2023-03-14

我实现了两个线程,一个打印整数,另一个打印英文字母。这些线程应该串联工作。

我使用同步块,一次只有一个线程将保持锁。但不知何故,AtomicInteger 没有按预期工作。一个线程对计数变量所做的更改对其他不同线程不可见。这怎么可能。我错过了什么吗?

我的实施

package com.concurrency;

导入java.util.concurrent.atomic.原子整数;

公共类ThreadWaitEg{

// Single monitor object for both threads
private final Object monitor = new Object();
// Thread-safe counter for both threads
private final AtomicInteger count = new AtomicInteger(0);

private class PrintNumber implements Runnable 
{

    @Override
    public void run() 
    {
        for (int i = 0; i < 26; i++) 
        {
            synchronized (monitor) 
            {
                System.out.println("From PrintNumber "+count.get());
                try 
                {
                    while ((count.get()) % 2 != 0) 
                    {
                        monitor.wait();
                    }

                } catch (InterruptedException e) 
                {
                    e.printStackTrace();
                }
                System.out.println(i);
                count.getAndIncrement();
                monitor.notifyAll();

            }
        }

    }

}

private class PrintChar implements Runnable 
{

    @Override
    public void run() 
    {

        for (int charr = 'A'; charr <= 'Z'; charr++) 
        {
            synchronized (monitor) 
            {
                System.out.println("From PrintChar "+count.get());
                try 
                {
                    while ((count.get()) % 2 == 0) 
                    {
                        monitor.wait();
                    }

                } catch (InterruptedException e) 
                {
                    e.printStackTrace();
                }
                System.out.println((char) charr);
                count.getAndIncrement();
                monitor.notifyAll();
            }
        }
    }

}

public static void main(String[] args) 
{
    System.out.println("from main thread");
    Runnable runInt = new ThreadWaitEg().new PrintNumber();
    new Thread(runInt).start();
    Runnable runChar = new ThreadWaitEg().new PrintChar();
    new Thread(runChar).start();
    System.out.println(" main thread completes ");
}

}

输出

从主线程 从打印编号 0 0 从打印


编号 1 主
线程完成
从打印字符 0

共有1个答案

柳梓
2023-03-14

您的主要问题是您创建了主ThreadWaitEg类的两个实例——每个实例都有自己的“monitor”和“count”对象的副本,因此这些对象不能在两个线程之间共享。最快的解决方法是只创建一个实例,也就是说,将main()方法替换为:

public static void main(String[] args) {
    System.out.println("from main thread");
    ThreadWaitEg threadWaitEg = new ThreadWaitEg();
    Runnable runInt = threadWaitEg.new PrintNumber();
    new Thread(runInt).start();
    Runnable runChar = threadWaitEg.new PrintChar();
    new Thread(runChar).start();
    System.out.println(" main thread completes ");
}
 类似资料:
  • 这是我的代码: 它抛出以下错误: 致命错误:未捕获的PDOExc0019: SQLSTATE[HY000]:常规错误: 2014当其他未缓冲的查询处于活动状态时,无法执行查询。考虑使用PDO语句::fetchAll()。或者,如果您的代码只针对mysql运行,您可以通过设置PDO::MYSQL_ATTR_USE_BUFFERED_QUERY属性来启用查询缓冲。--plhd--3/>(71): PD

  • 问题内容: 当我启动redis集群的所有redis服务器时,所有这些服务器都会连续打印日志,如WSA_IO_PENDING clusterWriteDone 问题答案: 由于日志记录语句使用最高级别,因此无法在Redis for Windows的3.2.x端口中专门关闭这些“警告” 。在我未维护的MSOpenTech仓库(我已将其更新为Redis 4.0.2)的分支中曾报告过此问题,并已将该级别降

  • 问题内容: 该程序输出- 它不应该提供输出- 因为首先ai应该打印1,然后执行a.getI()并应该打印A 2 问题答案: 在此表达式中: 首先评估对的调用,然后通过连接加号形成字符串

  • 问题内容: 我下面有一段代码,该代码创建了几个线程来执行任务,而单独运行效果很好。但是,我很难理解为什么在所有线程完成并调用该语句之前,我在函数中调用的打印语句不会执行。我希望它们在线程执行时被调用。有没有简单的方法可以做到这一点,为什么首先要这样做呢? 问题答案: 这是由于stdout缓冲引起的。您仍然可以刷新缓冲区: 您可以在此处和此处找到有关此问题的更多信息。

  • 我制作了一个程序,要求用户输入5位数字,然后程序将查找这些数字的总和。我想知道我怎样才能使程序在计算一次之后一遍又一遍地要求一个数字。我希望用户再试一次,直到他自己想退出。

  • 我有一个带有静态ConcurrentQueue的类。一个类接收消息并将其放入队列中,而这个类上的另一个线程从该队列中读取消息并一次处理一个。使用cancellationtoken中止该方法。 清空队列的方法如下所示: 我的测试方法如下: 因此,我在自己的线程中启动我的出列方法,并使用一个新的取消令牌。然后我将一些消息排队,给进程一秒钟时间来处理它们,然后使用源代码。Cancel(false)结束线