【问题标题】:Sequential thread execution to print 1A 2B 3C 4D顺序线程执行打印 1A 2B 3C 4D
【发布时间】:2015-03-26 17:09:14
【问题描述】:

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

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

我的实现

package com.concurrency;

导入 java.util.concurrent.atomic.AtomicInteger;

公共类 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 ");
}

}

输出

来自主线程
从 PrintNumber 0
0
来自 PrintNumber 1
主线程完成
从 PrintChar 0

【问题讨论】:

  • 不是真正的问题,但您的一个循环将迭代 25 次,其他 26 次。
  • @AndyTurner:我对类进行了更改,现在两个循环都将迭代 26 次。
  • 您在monitor 上获得了一个互斥锁,然后在持有它的同时等待另一个同样希望monitor 上的互斥锁的线程通知第一个线程。我猜你遇到了僵局。
  • 在一个对象上持有互斥锁是可以的,在持有它的同时调用monitor.wait(),因为这将放弃锁并进入阻塞状态等待来自其他线程的信号。

标签: java multithreading thread-safety atomic


【解决方案1】:

您的主要问题是您创建了主 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 ");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多