Параллельность потока - Использование блокировки строкового объекта для синхронизации - PullRequest
0 голосов
/ 31 декабря 2011
class ZiggyTest{

    public static void main(String[] args){

        RunnableThread rt = new RunnableThread();

        Thread t1 = new Thread(rt);
        Thread t2 = new Thread(rt);
        Thread t3 = new Thread(rt);

        t1.start();
        t2.start();
        t3.setPriority(10);
        t3.start();

        try{
            t3.join();
            t2.join();
            t1.join();

            System.out.println("Joined");
        }catch(InterruptedException e){System.out.println(e);}


        Thread t4 = new Thread(new RunnableThread());
        Thread t5 = new Thread(new RunnableThread());
        Thread t6 = new Thread(new RunnableThread());

        t4.start();
        t5.start();
        t6.start();
    }

}

Приведенный выше тест дает следующий вывод

Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-2
Thread-2
Thread-2
Thread-2
Thread-2
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Joined
Thread-3
Thread-3
Thread-4
Thread-4
Thread-3
Thread-4
Thread-5
Thread-4
Thread-3
Thread-4
Thread-5
Thread-3
Thread-5
Thread-5
Thread-5

Я не понимаю, почему последние три потока не используют объект String в качестве общей блокировки, как первые три потока. Даже если последние три потока используют другой экземпляр RunnableThread, разве они не должны быть синхронизированы, потому что в пуле строковых констант есть только одна копия для str?

Спасибо

Редактировать

упс .. я забыл включить RunnableThread.

class RunnableThread implements Runnable{

    String str = "HELLO";

    public void run(){
        runMe();
    }

    public synchronized void runMe(){
        for (int a : new int[]{1,2,3,4,5}){
            System.out.println(Thread.currentThread().getName());
        }
    }
}

1 Ответ

5 голосов
/ 31 декабря 2011

Ваши потоки не синхронизируются ни с одним String объектом, не говоря уже о том же, так что я не уверен, откуда взялась эта идея.Они синхронизируются на самом объекте RunnableThread благодаря ключевому слову synchronized в этой строке:

public synchronized void runMe(){

Использование отдельных RunnableThread объектов для трех последних потоков означает, что они работают независимо.

Теперь, если вы действительно хотите заблокировать этот глобальный String объект, метод будет выглядеть как

public void runMe(){
    synchronized (str) {
        for (int a : new int[]{1,2,3,4,5}){
            System.out.println(Thread.currentThread().getName());
        }
    }
}

, и было бы неплохо сделать str final.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...