Strange problems of simple multithreaded programs in Java

I just started playing multithreaded programming I want my program to alternate the characters' – 'and', but that's not the case My task is to use the synchronized keyword So far, I have:

class FunnyStringGenerator{

    private char c;

    public FunnyStringGenerator(){
        c = '-';
    }

    public synchronized char next(){

        if(c == '-'){
            c = '+';
        }
        else{
            c = '-';
        }

        return c;
    }
}

class ThreadToGenerateStr implements Runnable{

    FunnyStringGenerator gen;

    public ThreadToGenerateStr(FunnyStringGenerator fsg){
        gen = fsg;
    }

    @Override
    public void run() {
        for(int i = 0; i < 10; i++){

            System.out.print(gen.next());
        }
    }


}

public class Main{


    public static void main(String[] args) throws IOException {

        FunnyStringGenerator FSG = new FunnyStringGenerator();

        ExecutorService exec = Executors.newCachedThreadPool();

        for(int i = 0; i < 20; i++){
            exec.execute(new ThreadToGenerateStr(FSG));
        }

    }

}

Editor: I also test thread in the run method Sleep, not loop

Solution

You are in funystringgenerator The synchronization block in next () works normally It will alternate between "return" and '–'

But you're in threadtogenerate str There is a race condition in run():

System.out.print(gen.next());

This is equivalent to:

char c = gen.next(); // Synchronized
System.out.print(c); // Not synchronized

The problem occurred:

>Thread 1 calls gen.next() to get the result of '–' > thread 2 calls gen.next() to get the result of '–' > thread 2 calls system out. Print(), write "> thread 1 calls system out. Print(), write '–‘

The results are "and" - "written in reverse order

There are various possible solutions, such as:

> calling gen.next () and System. in a single synchronous block. out. Print() (such as dogbane's answer) > make gen.next() writes characters to the stream instead of returning it > make gen.next() attaches the characters to the shared BlockingQueue, and a dedicated I / O thread obtains characters from the queue and prints them

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>