2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Работа с lock в JAVA
Сообщение18.04.2014, 00:37 
Код:
//подключаем библиотеки
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
//Producer
class Producer implements Runnable{
   Lock lock;
   Lock lockN;
   Lock lock0;
   
   Producer(Lock lock, Lock lockN, Lock lock0){
      this.lock = lock;
      this.lockN = lockN;
      this.lock0 = lock0;
   }
   
   public void produce(int ii){
      //пытаемся блокировать lock
      lock.lock();
      try{   
         System.out.println("Producer iteration");
         while(Threads.s == Threads.N){
            lock.unlock();
            lock.lock();
         }
            Threads.s += 1;
         System.out.println(Threads.s+" "+ii);
      }
      finally{
         lock.unlock();
      }

   }
   //секция выполнения
   public void run(){
      for(int i = 0; i < 10; i++){
         produce(i);
      }
   }


}


class Consumer implements Runnable{
   Lock lock;
   Lock lockN;
   Lock lock0;
   Consumer(Lock lock, Lock lockN, Lock lock0){
      this.lock = lock;
      this.lock0 = lock0;
      this.lockN = lockN;

   }

   public void consume(int ii){
      lock.lock();
      try{
         System.out.println("Consumer iteration");
         while(Threads.s==0){
            lock.unlock();
            lock.lock();
         }
            Threads.s -= 1;
         System.out.println(Threads.s+" "+ii);
      }
      finally{
         lock.unlock();
      }

   }

   public void run(){
      for(int i = 0; i < 10; i++){
         consume(i);
      }
   }
}

public class Threads{
   public static int s;
   public static int N;
   public static void main(String Args[]){
      s = 0;
      N = 4;
      //запускаем произвольное кол-во thredo'в
      ExecutorService exec = Executors.newCachedThreadPool();
      Lock lock = new ReentrantLock();
      Lock lockN = new ReentrantLock();
      Lock lock0 = new ReentrantLock();
      
      exec.submit(new Producer(lock, lockN, lock0));
      exec.submit(new Consumer(lock, lockN, lock0));
      //закрываем thread'ы;
      exec.shutdown();
   }
}

/* Producer увеличивает значение счётчика Threads.s  на 1 , как только счётчик = 4 ==> останавливается. */


Если запустить программу без lockN, lock0 - выводит

Цитата:
producer iteration
consumer iteration
и зависает.

Вопрос : зачем в программе нужны lockN и lock0 ?

 
 
 
 Re: Работа с lock в JAVA
Сообщение18.04.2014, 01:21 
Аватара пользователя

(Оффтоп)

Sshhookkeerr в сообщении #851100 писал(а):
Код:
//подключаем библиотеки
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
Зачем и кому нужны комментарии подобного сорта?

 
 
 
 Re: Работа с lock в JAVA
Сообщение18.04.2014, 12:44 
Sshhookkeerr в сообщении #851100 писал(а):
Вопрос : зачем в программе нужны lockN и lock0 ?
Даже не зная Java, с высокой степенью вероятности можно утверждать, что ни зачем не нужны. По крайней мере, в данной программе (можно предположить, что они нужны, но код, который должен их использовать, еще не дописан; но об этом Вам лучше должно быть известно :-) ). У меня что с ними, что без них она выводит одно и то же. Разное поведение у Вас может быть вызвано не их наличием/отсутствием, а совсем другими причинами (что вполне возможно в многопоточных программах).

 
 
 
 Re: Работа с lock в JAVA
Сообщение18.04.2014, 15:35 
Нда. while(!condition) { lock.unlock(); lock.lock(); } — это жестоко, в приличном обществе используют Condition:

Код:
    Producer(Lock lock, Condition notEmpty, Condition notFull){ ... }
    // ...

    public void produce(int ii){
        lock.lock();
        try{   
            System.out.println("Producer iteration");
            // возвращение из await не гарантирует, что Threads.s != Threads.N, поэтому здесь while, а не if
            while (Threads.s == Threads.N) {
                notFull.await();
            }
            Threads.s += 1;
            System.out.println(Threads.s+" "+ii);
            notEmpty.signal();
        }
        finally{
            lock.unlock();
        }
    } 

    // ...

    Consumer(Lock lock, Condition notEmpty, Condition notFull){ ... }
    // ...

    public void consume(int ii){
        lock.lock();
        try{
            System.out.println("Consumer iteration");
            while (Threads.s==0){
                notEmpty.await();
            }
            Threads.s -= 1;
            System.out.println(Threads.s+" "+ii);
            notFull.signal();
        }
        finally{
            lock.unlock();
        }
    }

    Lock lock = new ReentrantLock();
    Condition notEmpty = lock.newCondition();
    Condition notFull = lock.newCondition();

    exec.submit(new Producer(lock, notEmpty, notFull));
    exec.submit(new Consumer(lock, notEmpty, notFull));

 
 
 
 Re: Работа с lock в JAVA
Сообщение19.04.2014, 14:23 
Вопрос закрыт, всем спасибо за помощь.

 
 
 [ Сообщений: 5 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group