java根类Object的方法

2018-06-02  本文已影响0人  pluss

toString()、equals(Object obj)、hashcode()、clone()、finalize()、wait()、notify()、notifyAll()、Class<?> getClass()

必须与synchroized一起使用,因为只有获得锁后才能wait和notify,否则抛出异常java.lang.IllegalMonitorStateException。


可以使用wait和notify函数来实现线程间通信,但是在java.util.concurrent包中提供了更高级的工具,没有必要使用wait和notify。
生产者消费者问题中,应该被synchronized的对象是缓冲区队列。
如果缓冲区队列满了,那么生产者线程应该等待。
如果缓冲区队列为空,那么消费者线程应该等待。

Producter
synchronized(list) {
  while(list.size()==maxSize){
    try{
      list.wait();
    } catch(Exception e) {
      e.printStackTrace();
    }
    
  }
    list.add(new Random().nextInt());
    list.notifyAll();
}

Consumer
synchronized(list) {
  while(list.isEmpty()){
    try{
      list.wait();
    } catch(Exception e) {
      e.printStackTrace();
    }
    
  }
    list.remove();
    list.notifyAll();
}

使用阻塞队列LinkedBlockingQueue解决生产者消费者问题。
BlockingQueue接口 是一个线程安全的可用于存取对象的队列。

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class Producer implements Runable {
  protected BlockingQueue<Object> queue;
  Producer(BlockingQueue<Object> queue) {
    this.queue = queue;
  }
  public void run() {
    try {
      while(true) {
        queue.put(new Object()); //队列满了会阻塞当前线程直到消费者线程从队列中取走资源
      }
    } catch(InterruptedException e) {
      System.out.println("Producer interrupted");
    }
  }
}

class Consumer implements Runable {
  protected BlockingQueue<Object> queue;
  Consumer (BlockingQueue<Object> queue) {
    this.queue = queue;
  }
  public void run() {
    try {
      while(true) {
        queue.take(); //队列为空会阻塞当前线程直到生产者线程生产资源
      }
    } catch(InterruptedException e) {
      System.out.println("Producer interrupted");
    }
  }
}

public class ProducerConsumerExample {
    public static void main(String[] args) throws InterruptedException {
        int numProducers = 4;
        int numConsumers = 3;

        BlockingQueue<Object> myQueue = new LinkedBlockingQueue<>(20);

        for (int i = 0; i < numProducers; i++) {
            new Thread(new Producer(myQueue)).start();
        }

        for (int i = 0; i < numConsumers; i++) {
            new Thread(new Consumer(myQueue)).start();
        }

        // Let the simulation run for, say, 10 seconds
        Thread.sleep(10 * 1000);

    }
}

上一篇 下一篇

猜你喜欢

热点阅读