线程关于wait,notify,notifyAll及Lock的学习(买卖)

1、notify、notifyAll和wait()都必须用在线程同步当中。在非线程同步中使用是绝对不允许的。当前线程调用notify作用是唤醒其他线程,但前提是必须拥有对象监视器(对象锁)。当前线程调用wait()作用是释放当前锁对象,让其他线程获得对象锁。

2、等待和唤醒必须是同一把锁。

/**以下是我学习的例子*/


//第一个demo

1、一个简单的类

public class Person {
	
	public int num=1;
	public boolean flag=false;

}

2、一个简单的类,主要是对num++。

class AddClass implements Runnable{
	
	private Person person;
	public AddClass(Person person){
		this.person=person;
	}

	@Override
	public void run() {
		
		while (true) {
			synchronized (person) {
				
				if (person.flag)//true
					try {
						person.wait();//等待,释放锁对象
						} catch (Exception e) {}
					
				person.num++;	//先执行运行,在作加操作
				System.out.println("加法"+"num="+person.num);
				person.flag=true;
				//唤醒线程池中等待的线程,一般是JVM将最先等待的线程唤醒,获得对象锁
				//调用该方法后,会往回执行一边,知道调用wait()方法
				person.notify();
				
			}
		}
		
	}
	
}
3,、这个也很简单

class DeleteClass implements Runnable{

	private Person person;
	public DeleteClass(Person person){
		this.person=person;
	}
	
	@Override
	public void run() {
		
		while (true) {
			synchronized (person) {
				
				if (!person.flag)
					try {
						person.wait();//等待,释放锁对象
						} catch (Exception e) {}
					
				person.num--;	//先执行运行,在作加操作
				System.out.println("减法"+"num="+person.num);
				person.flag=false;	
				person.notify();//唤醒操作
				
			}
		}
	}
	
}
/**********************************************************************************************************************************/

//第二个demo

	/**
	 * 线程池的内部结构类似队列,线程严格遵守先进先出的规则工作*/

public class Main {


	public static void main(String[] args) {

		Person person=new Person();
		
		Add add=new Add(person);
		Delete del=new Delete(person);
		
		new Thread(add).start();
		new Thread(add).start();
		new Thread(del).start();
		new Thread(del).start();
		new Thread(add).start();
		
	}

}

class Person{
	
	public int count;
	public boolean flag=false;
	
	public synchronized void in(){
		while (flag) {//此处用if判断将会出现生产者连续生产两次
			
			try {
				
				this.wait();//放弃对象锁
				
			} catch (InterruptedException e) {}
			
		}	
			count++;
			System.out.println(Thread.currentThread().getId()+"生产者....."+count);
			flag=true;
			this.notifyAll();//唤醒线程池所有的等待线程
			
	
		
	}
	
	public synchronized void out(){
		
		while (!flag) {
			
	        try {
					
					this.wait();//放弃对象锁
					
				} catch (InterruptedException e) {}
			
		}
		flag=false;
		System.out.println(Thread.currentThread().getId()+"消费者..............."+count);
		this.notifyAll();//唤醒线程池所有的等待线程
	}

}

/**
 *两个线程都是操作同一个对象的 */
class Add implements Runnable{
	
	private Person person;
	
	public Add(Person person){
		this.person=person;
	}
	
	public void run() {
		while (true) {
			person.in();
		}
		
	}
}

class Delete implements Runnable{


	private Person person;
	
	public Delete(Person person){
		this.person=person;
	}
	
	@Override
	public void run() {
		
		while (true) {
			person.out();
		}
	}
	
}

/**运行结果
	 * 8生产者.....1
	10消费者...............1
	9生产者.....2
	11消费者...............2
	12生产者.....3*/
/***********************************************************************************/

//这是一个有关jdk 1.5及只有的Lock

* 线程池的内部结构类似队列,线程严格遵守先进先出的规则工作*/

/**
 * Lock其实就是Syncnized中的锁对象,而Condition中sinal,sinalAll,await,的方法分别类似于notify,notifyAll,wait()
 * 其实Lock和Syncronized类似,只是表现形式不同*/

public class Lock {

    
    
	public static void main(String[] args) {
		
		

		Person person=new Person();
		
		Add add=new Add(person);
		Delete del=new Delete(person);
		
		new Thread(add).start();
		new Thread(add).start();
		new Thread(del).start();
		new Thread(del).start();
		new Thread(add).start();
		
	}

}

class Person{
	
	public int count;
	public boolean flag=false;
	
	ReentrantLock lock=new ReentrantLock();//锁实例
	Condition condition_in=lock.newCondition();//负责唤醒对方的condition
	Condition condition_out=lock.newCondition();//负责唤醒对方的condition
	
	public  void in(){
		
		lock.lock();//锁住
		try {
			
			while (flag) {//此处用if判断将会出现生产者连续生产两次
				
				//用condition_in等待,用condition_out唤醒
				condition_in.await();//放弃对象锁
			}	
				count++;
				System.out.println(Thread.currentThread().getId()+"生产者....."+count);
				flag=true;
				condition_out.signal();//只会唤醒对方的锁,不会唤醒本方的锁,
//			    condition_in.signalAll();//唤醒所有的
		} catch (Exception e) {
			
		}finally{
			lock.unlock();//释放锁
		}

		
			
	
		
	}
	
	public void out(){
		
		lock.lock();
		try {
			
			while (!flag) {
				
				condition_out.await();//放弃对象锁
			}
			
			flag=false;
			System.out.println(Thread.currentThread().getId()+"消费者..............."+count);
			condition_in.signal();
			
		} catch (Exception e) {
			
		}finally{
			lock.unlock();
		}
		
	}

}

/**
 *两个线程都是操作同一个对象的 */
class Add implements Runnable{
	
	private Person person;
	
	public Add(Person person){
		this.person=person;
	}
	
	public void run() {
		while (true) {
			
			person.in();
			
		}
		
	}
}

class Delete implements Runnable{


	private Person person;
	
	public Delete(Person person){
		this.person=person;
	}
	
	@Override
	public void run() {
		
		while (true) {
			person.out();
		}
	}
	
}

/**运行结果
	 * 8生产者.....1
	10消费者...............1
	9生产者.....2
	11消费者...............2
	12生产者.....3*/
点击下载





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值