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();
	}
}

在这里插入图片描述

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

猜你喜欢

转载自blog.csdn.net/taiguolaotu/article/details/107709772
今日推荐