Question

So I have a code:

public void runThreads(int number)
{
    List<Thread> threadList = new ArrayList<Thread>();
    for (int i = 0; i < number; i++)
    {
        Thread t = new MyThread(getRandomPerson(),i);
        threadList.add(t);
    }

    for (Thread x : threadList)
    {
        x.start();
    }
}

So I am adding threads to my list of threads and then starting this threads. This is MyThread class:

public class MyThread extends Thread
{
    Person person;
    int number;

    public MyThread(Person person, int number)
    {
        this.person = person;
        this.number = number;
    }
    @Override
    public void run()
    {
        try
        {
            synchronized (this)
            {
                Thread.sleep(1000);
                System.out.println(number + "\t" + person.getSurname());
                Thread.sleep(1000);
                System.out.println(number + "\t" + person.toString());
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

I wanted to make a program which creates the threads, adds them to the list, invokes them but each thread should wait until the previous ended its task. So output should be like :

1 Surname
/** Waitning second */
1 person.toString()
/** Waiting second*/
And then the second thread start invoking:
2 Surname
....

How to achieve this using synchronized? I tried different ways to use synchronized but it failed.

Était-ce utile?

La solution

public class MyThread extends Thread
{

    private static Object lock = new Object();

...
            synchronized (lock)
            {
                Thread.sleep(1000);
                System.out.println(number + "\t" + person.getSurname());
                Thread.sleep(1000);
                System.out.println(number + "\t" + person.toString());
            }
...

That way you will get the same person's surname and toString() in order. You won't enforce strict ordering on the people, person 7 may still go before person 1.

Autres conseils

You need a common lock - at the moment you are synchronizing on this, which is different for each thread. Try something like:

private static final Object lock = new Object();

and synchronize on that static (therefore shared) variable instead.

If you must use threads and if you must have order of execution, then you can do a t.join() immediately after t.start() - this will ensure the following flow:

- Main Thread
      - loop
      - start child thread
      - wait for child thread to finish
      - continue loop
- Exit Main thread

But, as pointed before, you don't need threads to do this since you can see that there is absolutely no gain from this approach (apart from academical) and it's detrimental in fact.

And special thanks to @assylias.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top