java多线程的理解

sleep()是Thread类的特有方法,wait() 与 notify/notifyAll() 是Object类的方法,在执行两个方法时,要先获得锁,因此wait() 与 notify/notifyAll() 一般是在临界区内执行,就是在加了synchronized的代码中执行

当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。

 当执行notify/notifyAll方法时不会立即释放锁,会唤醒一个处于等待该对象锁的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。notify/notifyAll()执行后,并不立即释放锁,而是要等到执行完临界区中代码后,再释放。在实际编程中,我们应该尽量在线程调用notify/notifyAll()后,立即退出临界区。即不要在notify/notifyAll()后面再写一些耗时的代码。

 

  • Thread.sleep()让线程从 【running】 -> 【阻塞态】 时间结束/interrupt -> 【runnable】
  • Object.wait()让线程从 【running】 -> 【等待队列】notify -> 【锁池】 -> 【runnable】

 推荐的常用同步方法

(1)Object的wait() / notify()方法
(2)LockCondition的await() / signal()方法
(3)BlockingQueue阻塞队列方法(推荐)

wait() / notify()方法-同步代码块

		@Override
		public void run() {
			while (true) {
				synchronized (queue) {
					while ((queue.size() == Max_Size)) {
						System.out.println(getName() + " queue is full!!");
						try {
							queue.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					int i = new Random().nextInt(10);
					System.out.println(getName() + " put " + i + " into queue!");
					queue.add(i);
					try {
						Thread.sleep(new Random().nextInt(1000));
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					queue.notify();
				}
			}
		}

业务类内循环调度,需获取wait()/notify()对象的锁,方法上加锁不行,需要对Object.wait()的Object加锁。遇不满足条件则进入等待。

wait() / notify()方法-同步方法

	public static class Store {
		private final int MAX_SIZE = 10;
		private int count;
		
		public synchronized void add () throws Exception{
			if (count < MAX_SIZE) {
				count++;
				System.out.println(Thread.currentThread().getName()+" put "+count);
				this.notifyAll();
			}else {
				System.out.println(Thread.currentThread().getName()+" store is full!!");
				this.wait();
			}
		}
		
		public synchronized void remove () throws Exception{
			if (count >0) {
				count--;
				System.out.println(Thread.currentThread().getName()+" remove "+count);
				this.notifyAll();
			}else {
				System.out.println(Thread.currentThread().getName()+" store is empty!!");
				this.wait();
			}
		}
		
	}
	/*
	 * @author wsg
	 * 仓库类,提供添加和删除接口
	 */
	public static  class Productor extends Thread{
		private Store store;

		public Store getStore() {
			return store;
		}

		public void setStore(Store store) {
			this.store = store;
		}
		
		@Override
		public void run() {
			while(true){
				try {
					store.add();
					Thread.sleep(100);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
	}
	

该实现方式把同步业务放在了共享存储内,存储应该只有增删功能,不符合面向对象的思想。在函数上增加同步,在函数内使用this.wait(),函数上增加synchronized等于对该对象this加锁,然后使用this.wait(),与需要对Object.wait()的Object加锁不冲突。

具体实现可参考:https://blog.youkuaiyun.com/u010983881/article/details/78554671

参考:http://ifeve.com/thread-signaling/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值