Java并发编程---线程之间的通信问题

 一.线程之间的通信

           1.概念

            线程是操作系统中独立的个体,但这些如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体的必用方式之一.当线程存在通信指挥,系统间的交互性会更强大,在提高CPU利用率的同时还会使开发人员对线程任务在处理的过程中进行有效的把控和监督.

           

            2.代码示例

           2.1原生方式实现线程通信

package com.thread.message;

import java.util.ArrayList;
import java.util.List;

public class ListAdd1 {

	/**volatile加与不加的区别,可以换做notify与wait来代替*/
	private volatile static List list = new ArrayList();

	public void add() {
		list.add("bjsxt");
	}

	public int size() {
		return list.size();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final ListAdd1 list1 = new ListAdd1();
		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					for (int i = 0; i < 10; i++) {
						list1.add();
						System.out.println("当前线程: " + Thread.currentThread().getName() + "添加了一个元素..");
						Thread.sleep(1000);
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}, "t1");

		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				while(true){
					if(list1.size() == 5){
						System.out.println("当前线程收到通知: " + Thread.currentThread().getName() + "list size = 5 线程停止...");
						throw new RuntimeException();
					}
				}
			}
		},"t2");
		
		t1.start();
		try {
			Thread.sleep(5);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		t2.start();
	}

}

      2.2 使用wait/notify方法实现线程间的通信

package com.thread.message;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.omg.Messaging.SyncScopeHelper;

/**
 * wait notify方法 , wait释放锁,notify不释放锁
 * 使用同一对象的锁
 * @author Administrator
 *
 */
public class ListAdd2 {

	private volatile static List list = new ArrayList();

	public void add() {
		list.add("bjsxt");
	}

	public int size() {
		return list.size();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final ListAdd2 list2 = new ListAdd2();

		// 1.实例化出来一个lock
		// 当使用wait和notify的时候,一定要配合着synchronized关键字去使用
		final Object lock = new Object(); // 把对象当成一把锁
		final CountDownLatch countDownLatch = new CountDownLatch(1);

		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					synchronized (lock) {
						for (int i = 0; i < 10; i++) {
							list2.add();
							System.out.println("当前线程: " + Thread.currentThread().getName() + "添加了一个元素..");
							Thread.sleep(500);
							if (list2.size() == 5) {
								System.out.println("已经发出通知!");
								// countDownLatch.countDown();        //发出通知,并非锁,只是一个标志
								lock.notify();
							}
						}
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}, "t1");

		Thread t2 = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				synchronized (lock) {        //代码块加锁
					if (list2.size() == 5) {
						try {
							System.out.println("t2进入... ");
		//					countDownLatch.await();
							lock.wait();                     //收到notif通知这块就往下走
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}	
					}
					System.out.println("当前线程收到通知: " + Thread.currentThread().getName() + "收到通知 线程停止...");
					throw new RuntimeException();
				}
				
			}
		}, "t2");
		
		t2.start();   
		try {
			Thread.sleep(5);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		t1.start();
	}

}

    3.代码分析

使用wait/notify方法实现线程间的通信.(注意这两个方法都是Object类的方法.换句话说,Java为所有的对象都提供了这两个方法)

    3.1 wait和notify必须配合synchronized关键字使用

    3.2 wait方法释放锁,notify方法不释放锁



你可能感兴趣的:(Java,并发编程,Java并发包编程总结)