Home > Mobile >  How to get all the threads working even when we create a new one in the for loop?
How to get all the threads working even when we create a new one in the for loop?

Time:03-03

Following code executes but I want it to print a new String tmp of the same length as sample's length.

class T10 {
    static String tmp = "", sample = "Manipulate";
    public static void main(String args[]) {
        for(int i=0;i<sample.length();i  )
            new Thread10(i).t.start();
        System.out.println(tmp);
    }
}
class Thread10 implements Runnable {
    int i;
    Thread t;
    Thread10(int i) {
        t = new Thread(this, "Manipulator Thread : " i);
        this.i = i;
    }
    public void run() {
        T10.tmp =T10.sample.charAt(i);
    }
}

Here are some sample outputs:

Mnla
Maniplua
Mpia
Miap
Mu

CodePudding user response:

Firstly, you need to know two things:

  • you cannot change a string in Java. Code that looks like it's modifying a string is always creating a new string and discarding the former one
  • = is not a single operation - it's three operations (read, modify, write back).

You can imagine that in your code, when two threads read the string at the same time, they read the same value (e.g. "Man"). Then the first thread creates a new string (adding its own letter, e.g. "Mani") and the second thread creates another new string (e.g. "Manp"). Now they both put the reference to their new value into the field tmp; depending on which one "wins", one of the chars will never be seen by other threads. Note that in "real" programs the issue is more complex (optimization kicks in) and you really need to understand the Java Memory Model to write correct code.

To fix your problem, you need to:

  • Stop using strings (they cannot be modified, new strings need to take their places), use instead a mutable object that stores characters; a single object that all the threads see and can write to;

  • Make sure that this object "behaves correctly" when used with multiple threads (in Java, this means that the object is either concurrent or synchronized)

Actually, Java has a very old class (seldom used nowadays) that is perfect for your case: a StringBuffer.

Use a StringBuffer instead of a String for your tmp; then use append('x') instead of = 'x' for adding chars.

CodePudding user response:

Please tell us what output you expect from your code.

Generally spoken:

With your implementation you do start 10 threads (because your sample string has 10 letters). But you have absolutely no control over the order in which the threads are executed and the state of the tmp variable at this time.

This could cause mixed order of letter and letters overwriting one another (like seen in your output).

Once you specify what output you expect it will be possible to suggest a solution.

  • Related