2014-01-17 3 views
1

Создайте метод, который принимает целое число как аргумент и печатает на консоли. Доступ к этому методу осуществляется несколькими потоками. Если два или более потока вызовут метод с одинаковым значением, тогда только один поток должен позволить печатать значение, которое должны ждать другие потоки. Если значения отличаются друг от друга, все потоки должны позволять печатать значение. Я знаю, что интернинг поможет здесь, но интернационализация Java происходит до значений, меньших 128. После этого два Integer, имеющие одинаковое значение, являются разными объектами ... Можно ли это сделать? Любое положение для синхронизации при условииJava Concurrency на основе условия

+1

Где ваш код? –

+0

«Другая нить должна ждать» до чего? – JVMATL

+0

вы не синхронизируете по * условию * - вы синхронизируете объект, а затем (в вашем случае) выполняете логику в синхронизированном блоке на основе значения этого объекта в зависимости от того, соответствует ли оно условию. Но весь этот вопрос очень плохо определен. Например: что, если один поток вызывает с «4», а затем другие вызовы с «4» через минуту - что должно произойти? Пока вы не поймете (и не объясните), что * должно произойти, вам трудно помочь. Может ли каждое значение печататься только один раз, когда-либо? Если да, то что происходит с вызывающими потоками? Блокируют ли они навсегда? – JVMATL

ответ

1

требование о предотвращении нескольких потоков из печати такое же значение, но позволяет им печатать различные те

Самый простой способ предотвратить это, чтобы иметь набор Целые печатных уже. Поскольку вы печатаете, накладные расходы на использование блокировки тривиальны.

Set<Integer> printed = Collections.synchronizedSet(new HashSet<Integer>()); 

// when printing 
if (printed.add(num)) // will one be true the first time for each number 
    System.out.println("num: " + num); 

Можно ли это сделать?

Печать на консоли синхронизирована уже и независимо от того, что вы делаете, вся нить синхронизирует их печать независимо от того, что вы делаете. Добавление большего количества блокировок не изменит этого.

например. от PrintStream, который реализует System.out и ошибиться

public void println(String x) { 
    synchronized (this) { 
     print(x); 
     newLine(); 
    } 
} 

Вы не можете просто принять решение игнорировать в synchronized здесь от вызывающего абонента.

Любые условия для синхронизации при условии ???

Проще всего сделать это, чтобы заблокировать другой замок или нить локальную. Заблокировать незащищенный объект очень быстро.

например.

synchronized(shared ? sharedObject : Thread.currentThread()) { 

} 

BTW Это очень странно/запутанная вещь. Я бы серьезно подумал об изменении дизайна, поэтому это не требуется. Написание нормального многопоточного кода достаточно сложно написать/понять.

+1

Я не думаю, что это вполне отвечает тому, что он задавал (хотя вопрос довольно расплывчатый, поэтому я не уверен на 100%, что было задано.) - как этот ответ отвечает требованию о предотвращении печати нескольких потоков одним и тем же * значением, но позволяя им печатать разные? Несмотря на странное описание, это звучит как важная часть вопроса. – JVMATL

+0

@JVMATL вы не можете одновременно печатать несколько потоков. System.out уже синхронизирован, вы не можете легко синхронизировать его и не хотите. –

+1

Я получаю, что System.out синхронизирован, но из описания пользователя неясно, что синхронизация на System.out для предотвращения перепечатки распечаток на самом деле является сутью его вопроса; он, кажется, спрашивает, как делать что-то * по-другому, если его метод вызывается с «тем же значением», если он вызывается с разными значениями, и я просто говорю, что этот ответ на самом деле не затрагивает этого. Если бы все, о чем он заботился, мешало его отпечаткам чередовать, то почему он даже упоминал, были ли эти ценности одинаковыми или разными? (и нет, я не могу понять, что он хочет делать) – JVMATL

Смежные вопросы