System.out.printf()语句是异步的吗? [英] is System.out.printf() statement asynchronous?

查看:129
本文介绍了System.out.printf()语句是异步的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在打印信息以使用可重入锁测试线程.我正在使用语句new ReentrantLock(true)创建公平锁.

I am printing information to test Threads using Reentrant locks. I am creating fair locks using statement new ReentrantLock(true).

在我正在使用锁的一种对象方法中,我正在使用例如方法

In one of the object method where I am using lock, I am using method e.g.

method() {
    for (int n = 0; n < 3; n++) {
       System.out.printf("%s: processing data \n",
            Thread.currentThread().getName(), data.get());
       TimeUnit.SECONDS.sleep(1);
    }
}

我正在创建10个线程,所有线程应在执行此控制台打印语句的地方执行3次相同的语句.但是,我没有看到每个线程都以相同的顺序显示打印内容的输出.例如

I am creating 10 threads and all threads should executing same statement 3 times where this console print statement is executed. however, I am not getting output where I see every thread showing the print in same sequence. e.g.

Thread 1: processing data hjjjj
Thread 2: processing data ghhjj
Thread 3: processing  data uiyiii
Thread 2: processing data ghfrtu
......
......

我期望如下:

Thread 1: processing data hjjjj
Thread 2: processing data ghhjj
Thread 3: processing  data uiyiii
Thread 1: processing data uiyuii

是因为公平起了作用,但system.out.println的打印顺序与发出的打印命令的顺序不同?

is it because fairness is at play but system.out.println is not printing in same sequence as sequence of print commands issued?

这是我的课程.

public class PriceInfo {
    private double price1 =1d, price2=2d;
    ReadWriteLock lock = new ReentrantReadWriteLock(true);

    public double getPrice1() {
        lock.readLock().lock();
        try{
            return price1;
        }finally{
            lock.readLock().unlock();
        }
    }

    public double getPrice2() {
        lock.readLock().lock();
        try{
            return price2;
        }finally{
            lock.readLock().unlock();
        }
    }

    public void getPrices() {
        lock.readLock().lock();
        try{
            synchronized (System.out) {
                System.out.printf("%s: price1 = %f and price2 = %f \n",        Thread.currentThread().getName(), price1, price2);
                System.out.flush();
            }
        }finally{
            lock.readLock().unlock();
        }
    }

    public void setPrices(double p1, double p2) {
        lock.writeLock().lock();
        try{
            System.out.println(Thread.currentThread().getName() + ": starting to set new prices ");
            price1 = p1;
            price2 = p2;
            System.out.println(Thread.currentThread().getName() + ": prices changed to price1:"+ p1 + "price2: "+ p2);
        }finally{
            lock.writeLock().unlock();
        }
    }
}

现在还有另一堂课.

public class Reader implements Runnable {

    private PriceInfo info;
    public Reader(PriceInfo inf) {
        info = inf;
    }
    @Override
    public void run() {
        for (int i=0; i<2; i++) {
            info.getPrices();
        }
     }
}

最后,我们有编写器线程和主类.

And finally, we have writer thread and main class..

public class Writer implements Runnable{

    private PriceInfo info;
    public Writer(PriceInfo inf) {
        info = inf;
    }
    @Override
    public void run() {
        for (int i=0; i<2; i++) {
                info.setPrices(new Double(Math.random()*10).doubleValue(), new Double(Math.random()*9).doubleValue());
            try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }
    }

    public static void main(String[] args) {

        PriceInfo pricesInfo=new PriceInfo();

        // create 5 threads and 5 readers
        Reader readers[]=new Reader[5];
        Thread threadsReader[]=new Thread[5];
        for (int i=0; i<5; i++){
            readers[i]=new Reader(pricesInfo);
            threadsReader[i]=new Thread(readers[i],("Thread" + i));
        }

        // create  writer thread

        Writer writer=new Writer(pricesInfo);
        Thread threadWriter=new Thread(writer,"WriterThread");

        for (int i=0; i<5; i++){
                threadsReader[i].start();
            }
            threadWriter.start();
    }
}

我得到以下输出.

   Thread0: price1 = 1.000000 and price2 = 2.000000 
   Thread4: price1 = 1.000000 and price2 = 2.000000 
   Thread3: price1 = 1.000000 and price2 = 2.000000 
   Thread2: price1 = 1.000000 and price2 = 2.000000 
   Thread1: price1 = 1.000000 and price2 = 2.000000 
   WriterThread: starting to set new prices 
   WriterThread: prices changed to price1:3.971662648848391price2: 8.604830021768233
   Thread0: price1 = 3.971663 and price2 = 8.604830 
   Thread1: price1 = 3.971663 and price2 = 8.604830 
   Thread2: price1 = 3.971663 and price2 = 8.604830 
   Thread3: price1 = 3.971663 and price2 = 8.604830 
   Thread4: price1 = 3.971663 and price2 = 8.604830 
   WriterThread: starting to set new prices 
   WriterThread: prices changed to price1:3.0036555312769297price2: 5.15672274505239

因此,您可以看到执行的线程序列是 线程0,线程4,3,2,1,写者,0,1,2,3,4 而我希望按照公平政策,我们应该有相同的顺序,例如0,4,3,2,1 0,4,3,2,1.

so, as you can see that sequence of threads executing are thread0, thread4,3,2,1,writer,0,1,2,3,4 whereas i am expecting as per fair policy that we should have same sequence such as 0,4,3,2,1 0,4,3,2,1.

我的代码有问题吗?还是公平政策不严格?

推荐答案

我正在创建10个线程,所有线程应在执行此控制台打印语句的地方执行3次相同的语句.但是,我没有看到每个线程都以相同的顺序显示打印内容的输出.例如

I am creating 10 threads and all threads should executing same statement 3 times where this console print statement is executed. however, I am not getting output where I see every thread showing the print in same sequence. e.g.

使用线程很难获得(并且不需要)特定的输出序列. System.out.printf(...) synchronized 操作,因此输出永远不会相互重叠,但是由于一次运行多个线程所固有的竞争条件,输出行的顺序是不可预测的.就异步(与线程同步无关)而言,默认情况下System.out启用了自动刷新功能,因此对PrintStream的所有写操作都会在每次写操作时刷新.

A specific sequence of output is hard (and unnecessary) to get with threads. System.out.printf(...) is a synchronized operation so the output will never overlap each other, but the order of the output lines is unpredictable because of the race conditions inherent in running multiple threads at one time. In terms of asynchronous (which has nothing to do with thread synchronization), by default System.out has auto-flush enabled, so all writes to a PrintStream get flushed on every write.

线程化应用程序输出的特定顺序是一个常见问题解答.在这里查看我的答案:在多线程中不需要的输出

Specific order of output of threaded applications is a FAQ. See my answer here: unwanted output in multithreading

引用答案,由于硬件,竞争条件,时间分段随机性和其他因素,无法预测线程运行的顺序.

To quote from the answer, the order that threads run cannot be predicted due to hardware, race-conditions, time-slicing randomness, and other factors.

这篇关于System.out.printf()语句是异步的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆