wait notify线程间的通信机制 应用在生产者消费者的典型问题上以及jdk5.0中synchronized不用的情况下使用Lock对象

代码

public class TestProducerConsumer {
    public static void main(String[] args) {
        MyStack stack = new MyStack();

        Runnable task1 = new Runnable(){
            public void run(){
                for(char c = 'A' ; c<='Z' ; c++){
                    stack.push(c+"");
                }
            }
        };
        Runnable task2 = new Runnable(){
            public void run(){
                for(int i = 1 ; i <= 26; i++){
                    stack.pop();
                }
            }
        };
        new Thread(task1).start();
//        new Thread(task1).start();
//        new Thread(task2).start();
        new Thread(task2).start();
    }
}

class MyStack{
    String[] data = {"","","","","",""};
    int index;

    public synchronized void push(String s){
            while (data.length == index) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.print(s + " pushed   ");
            data[index] = s;
            index++;
            print();
            this.notifyAll();//只要执行生产者(数组中增加元素)就要通知消费者
			//释放消费者线程,但是不释放锁标记。这个同步方法执行完毕,会
			//释放锁标记
    }

    public synchronized void pop(){
            while (index == 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            index--;
            String o = data[index];
            data[index] = "";
            System.out.print(o + " poped    ");
            print();
            this.notifyAll(); //只要执行消费者(将数组中元素进行出栈) 就会通知生产者
            //释放生产者线程 ,但是不释放锁标记。这个同步方法执行完毕,会
			//释放锁标记
    }

    public void print(){
        for(int i = 0 ; i < data.length ; i++){
            System.out.print(data[i]+" ");
        }
        System.out.println();
    }
}

执行结果

A pushed   A      
B pushed   A B     
B poped    A      
A poped          
C pushed   C      
D pushed   C D     
E pushed   C D E    
F pushed   C D E F   
G pushed   C D E F G  
H pushed   C D E F G H 
H poped    C D E F G  
G poped    C D E F   
F poped    C D E    
E poped    C D     
D poped    C      
C poped          
I pushed   I      
I poped          
J pushed   J      
J poped          
K pushed   K      
K poped          
L pushed   L      
M pushed   L M     
M poped    L      
L poped          
N pushed   N      
O pushed   N O     
O poped    N      
N poped          
P pushed   P      
P poped          
Q pushed   Q      
R pushed   Q R     
S pushed   Q R S    
T pushed   Q R S T   
U pushed   Q R S T U  
V pushed   Q R S T U V 
V poped    Q R S T U  
U poped    Q R S T   
T poped    Q R S    
S poped    Q R     
R poped    Q      
Q poped          
W pushed   W      
X pushed   W X     
Y pushed   W X Y    
Z pushed   W X Y Z   
Z poped    W X Y    
Y poped    W X     
X poped    W      
W poped          

代码

public class TestNumberCharPrint {

	public static void main(String[] args) throws InterruptedException {
		final Object o = new Object();
		
		Runnable task1 = new Runnable(){
			public void run(){
				synchronized (o) {	//同一个o对象
					for (int i = 1; i <= 52; i++) {
						System.out.print(i);
						if (i % 2 ==0){
							o.notifyAll();//释放字母线程
							try {	
								if(i!=52) o.wait();	//同一个等待队列
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		};
		
		Runnable task2 = new Runnable(){
			public void run(){
				synchronized (o) {	//同一个o对象
					for (char c = 'A'; c <= 'Z'; c++) {
						System.out.print(c);
						o.notifyAll();//释放数字线程
						try {
							if (c!='Z') o.wait();	//同一个等待队列
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		};
		
		Thread t1 = new Thread(task1);
		Thread t2 = new Thread(task2);
		t1.start();
		Thread.sleep(1);
		t2.start();
	}

运行结果

12A34B56C78D910E1112F1314G1516H1718I1920J2122K2324L2526M2728N2930O3132P3334Q3536R3738S3940T4142U4344V4546W4748X4950Y5152Z

Lock代码

//jdk5.0中synchronized不用的情况下
public class TestProducerConsumer {
	public static void main(String[] args) {
		MyStack stack = new MyStack();

		Runnable task1 = new Runnable(){
			public void run(){
				for(char c = 'A' ; c<='Z' ; c++){
					stack.push(c+"");
				}
			}
		};
		Runnable task2 = new Runnable(){
			public void run(){
				for(int i = 1 ; i <= 26; i++){
					stack.pop();
				}
			}
		};
		new Thread(task1).start();
		new Thread(task1).start();
		new Thread(task2).start();
		new Thread(task2).start();
	}
}

class MyStack{
	String[] data = {"","","","","",""};
	int index;
	
	Lock lock = new ReentrantLock();	//锁对象
	//jdk5.0使用condition对象实现生产者消费者代码
	Condition full = lock.newCondition();		//通过锁对象获取Condition对象 获得等待队列  生产者
	Condition empty = lock.newCondition();		//获得等待队列   消费者
	
	public void push(String s){
		try {
			lock.lock();	//替换synchronized  作用一样都是(标记同步代码快)  进入同步代码快
			while (data.length == index) {
				try {
					full.await();	//等同于 Object类中wait()方法
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.print(s + " pushed   ");
			data[index] = s;
			index++;
			print();
			empty.signalAll();//通知消费者  等同于 Object类中notifyAll()方法
		} 
		finally{	
			lock.unlock();		//离开同步代码块
		}
	}
	public void pop(){
		try {
			lock.lock();
			while (index == 0) {
				try {
					empty.await();	//释放线程 同时释放对象锁标记
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			index--;
			String o = data[index];
			data[index] = "";
			System.out.print(o + " poped    ");
			print();
			full.signalAll(); //通知生产者	释放线程 不释放对象锁标记
		} 
		finally{
			lock.unlock();
		}
	}
	public void print(){
		for(int i = 0 ; i < data.length ; i++){
			System.out.print(data[i]+" ");
		}
		System.out.println();
	}
}

在这里插入图片描述

这辈子坚持与不坚持都不可怕,怕的是独自走在坚持的道路上!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生产者消费者问题是一种经典的多线程同步问题,主要涉及到生产者和消费者之的数据交换和同步。 在Java,可以使用多种方式来实现生产者消费者问题的解决方案,其最常用的方式是使用wait()和notify()方法来实现线程的同步。 下面是一个简单的示例,演示了如何使用wait()和notify()方法来实现生产者消费者问题的解决方案: ``` import java.util.LinkedList; import java.util.Queue; public class ProducerConsumer { private Queue<Integer> buffer = new LinkedList<>(); private final int capacity = 5; public void produce() throws InterruptedException { int value = 0; while (true) { synchronized (this) { while (buffer.size() == capacity) wait(); System.out.println("Producer produced-" + value); buffer.add(value++); notify(); Thread.sleep(1000); } } } public void consume() throws InterruptedException { while (true) { synchronized (this) { while (buffer.size() == 0) wait(); int val = buffer.poll(); System.out.println("Consumer consumed-" + val); notify(); Thread.sleep(1000); } } } } ``` 在上面的示例,ProducerConsumer类表示生产者消费者问题的解决方案。这个类有一个buffer队列,它是一个FIFO队列,用于存储生产者生产的数据。 produce()方法表示生产者的行为,它使用一个while(true)循环来不断地生产数据。在每次生产之前,它首先检查buffer队列是否已满。如果buffer队列已满,则调用wait()方法来等待消费者线程消费数据。如果buffer队列未满,则将生产的数据添加到buffer队列,并调用notify()方法通知消费者线程可以消费数据了。 consume()方法表示消费者的行为,它使用一个while(true)循环来不断地消费数据。在每次消费之前,它首先检查buffer队列是否为空。如果buffer队列为空,则调用wait()方法来等待生产者线程生产数据。如果buffer队列不为空,则从buffer队列取出一个数据,并调用notify()方法通知生产者线程可以生产数据了。 在上面的示例使用synchronized关键字来实现线程的同步。synchronized关键字可以确保在同一时只有一个线程可以执行被synchronized关键字包裹的代码块。wait()方法可以让线程等待,直到被notify()方法唤醒。notify()方法可以唤醒一个等待的线程。如果有多个线程等待,则只有一个线程会被唤醒。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值