콘텐츠로 이동

2023 03 14

2023-03-14

Java Monitor

  • Busy Waiting
    object ThreadCommunication extends App {
      class SimpleContainer {
        private var value: Int = 0
        def isEmpty: Boolean = value == 0
        def set(newVal: Int) = value = newVal
        def get: Int = {
          val result = value
          value = 0
          result
        }
      }
    
      def naiveProdCons(): Unit = {
        val container = new SimpleContainer
    
        // Busy waiting => Computing Waste
        val consumer = new Thread(() => {
          println("[consumer] waiting")
          while(container.isEmpty) {
            println("[comsumer] actively waiting")
          }
          println("[consumer] I have consumed " + container.get)
        })
    
        val producer = new Thread(() => {
          println("[producer] computing...")
          Thread.sleep(500)
          val value = 42
          println("[producer] I have produced after long work, the value " + value)
          container.set(value)
        })
    
        consumer.start()
        producer.start()
      }
    }
    
  • wait() & notify()
    def prodConsLargeBuffer(): Unit = {
        val buffer: mutable.Queue[Int] = new mutable.Queue[Int]
        val capacity = 3
    
        val consumer = new Thread(() => {
          val random = new Random()
    
          while (true) {
            buffer.synchronized {
              if (buffer.isEmpty) {
                println("[consumer] buffer empty, waiting...")
                buffer.wait()
              }
            }
            // there must be at least one value in the buffer
            val x = buffer.dequeue()
            println("[consumer] consumed " + x)
    
            // hey producer. there is empty space. Work!
            //        buffer.notify()
          }
    
          Thread.sleep(random.nextInt(500))
        })
    
        val producer = new Thread(() => {
          val random = new Random()
          var i = 0
    
          while (true) {
            buffer.synchronized {
              if (buffer.size == capacity) {
                println("[producer] buffer is full, waiting...")
                buffer.wait()
              }
    
              println("[producer] producing " + i)
              buffer.enqueue(i)
    
              // hey consumer! new food for you
              buffer.notify()
              i += 1
            }
            Thread.sleep(random.nextInt(500))
          }
        })
    
        consumer.start()
        producer.start()
    }
    
    prodConsLargeBuffer()