Два потока разделяют статическое логическое поле, но первый поток не завершает работу - PullRequest
1 голос
/ 09 февраля 2012

Я пытаюсь добиться того, чтобы создать 2 потока, совместно использующих общий статический логический ресурс, чтобы в зависимости от значений флага выходил первый поток, но первый поток все равно работал.

Это кодниже,

     class SharedResource08{    

        public synchronized void doIt() throws Exception{

            while(!SharedResource07.getBFlag()){
                System.out.println(" THE THREAD "+Thread.currentThread().getName());
                Thread.sleep(250);
            }   
        }

     }

     class SharedResource07{
        private static boolean bFLag = false;

        public static synchronized void setBFlag(boolean bFLag){        
            bFLag = bFLag;      
            System.out.println(" THREAD "+Thread.currentThread().getName()+" setting value bFLag := "+bFLag);
        }

        public static  boolean getBFlag(){
            return bFLag;
        }   

     }


     class MyThread07 extends Thread{

        private SharedResource08  resource;

        MyThread07(String threadName,SharedResource08 resource){
        super(threadName);
            this.resource = resource;
        }

        public  void run(){
            try{

                if(getName().equals("JACK")){
                    resource.doIt();
                }else if(getName().equals("JILL")){
                    SharedResource07.setBFlag(true);
                }

            }catch(Exception e){
                System.out.println(e);
            }
        }
     }


     public class Ex07{
        public static void main(String[] args){
            SharedResource08 resource = new SharedResource08();
            MyThread07 t1 = new MyThread07("JACK",resource);
            MyThread07 t2 = new MyThread07("JILL",resource);
            t1.start();
            t2.start();
        }   
     } 

Я ожидаю, что поток t1 выполнит метод doit () класса SharedResource08, в то время как второй поток t2 должен установить для флага bFLag класса SharedResource07 значение true, теперь один разэтот флаг имеет значение true, поток t1 должен выйти из метода doIt (),

, но этого не происходит, мой поток t1 продолжает печатать SOP.
Требуется некоторое предложение.

Ответы [ 4 ]

2 голосов
/ 09 февраля 2012

Просто типичная ошибка:

Изменить это:

public static synchronized void setBFlag(boolean bFLag){        
        bFLag = bFLag; // assigning the parameter to the parameter

для этого:

public static synchronized void setBFlag(boolean bFLag){        
        SharedResource07.bFLag = bFLag;  // assigning the parameter to the static field

Некоторые IDE хорошо умеют избегать ошибок такого рода, сигнализируя о предупреждениях в коде. Всегда держите Eclipse под рукой:)

2 голосов
/ 09 февраля 2012

Каждый поток может сделать свою собственную локальную копию любого поля, которое не объявлено volatile, если доступ не защищен блоком synchronized.

В вашем случае проще всего добавить ключевое слово volatile в ваше логическое поле, так как любые его обновления в любом случае будут атомарными (это будет одно логическое значение). В более сложных случаях требуется расширенная синхронизация.

Параллельность - довольно большой и тяжелый предмет в целом, но этот может помочь начать его решать.

1 голос
/ 09 февраля 2012

Ну, у тебя правильный ответ От нашего друга Гелиоса.проблема, с которой вы столкнулись, заключалась в том, что поток Jill на самом деле не изменяет класс SharedResource07 bFlag.

 SharedResource07.bFlag=bFlag;

Добавление volatile к статическому члену делает две вещи.1) значение переменной никогда не передается потокам локального ресурса. Оно будет храниться в основной памяти.2) доступ к этой переменной синхронизирован.

0 голосов
/ 09 февраля 2012

Я ожидаю, что поток t1 выполнит метод doit () класса SharedResource08

Не гарантируется, что ваш метод doIt () когда-либо запускается.Может возникнуть ситуация, когда поток «JILL» получит запланированное время раньше, перейдет в другую часть и установит флаг ресурсов.race condition

просто хотел указать на все вещи, указанные в другом коде.

Помимо всего, на что мы указываем volatile, это правильная вещь для использования.

вы тоже можете сделать это с Atomicboolean.Посмотрите на то же самое.Новый альтернативный подход к синхронизированной парадигме

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