线程通信

线程通信有三种方法:一是利用Obeject的wait,notify,notifyAll。二是利用condition配合lock。三是利用BlockingQueue接口,put方法,take方法。

方法一:

class Account {
	private String accountNo;
	private double balance;
	private boolean flag = false;
	public Account(){}
	
	public Account(String accountNo, double balance)
	{
		this.setAccountNo(accountNo);
		this.setBalance(balance);
	}


	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}
	
	public synchronized void draw(double drawAmount)
	{
		try
		{
			if(!flag)
			{
				wait();
			}
			else
			{
				System.out.println(Thread.currentThread().getName()+"取钱:" + drawAmount);
				balance -= drawAmount;
				System.out.println(Thread.currentThread().getName()+"取钱成功!吐出钞票:"+drawAmount);
				flag = false;
				notifyAll();
			}
		}
		catch(InterruptedException ex)
		{
			ex.printStackTrace();
		}
	}
	public synchronized void deposit(double depositeAmount)
	{
		try
		{
			if(flag)
			{
				wait();
			}
			else
			{
				System.out.println(Thread.currentThread().getName()+"存款:"+depositeAmount);
				balance += depositeAmount;
				System.out.println("账户余额为:"+ balance);
				flag = true;
				notifyAll();
			}
		}
		catch(InterruptedException ex)
		{
			ex.printStackTrace();
		}
	}

	public String getAccountNo() {
		return accountNo;
	}

	public void setAccountNo(String accountNo) {
		this.accountNo = accountNo;
	}
}


class DepositThread extends Thread {
	private Account account;
	private double depositAmount;
	public DepositThread(String name, Account account, double drawAmount)
	{
		super(name);
		this.account = account;
		this.depositAmount = drawAmount;
	}
	public void run()
	{
		for(int i = 0; i < 100; i ++)
		{
			account.deposit(depositAmount);
		}
	}
}

class DrawTest {
	public static void main(String[] args) {
		Account acct = new Account("1213", 0);
		new DrawThread("取钱者", acct, 800).start();
		new DepositThread("存钱者甲", acct, 800).start();
	}
}

public class DrawThread extends Thread {
	private Account account;
	private double drawAmount;
	public DrawThread(String name, Account account, double drawAmount)
	{
		super(name);
		this.account = account;
		this.drawAmount = drawAmount;
	}
	public void run()
	{
		for(int i = 0; i < 100; i ++)
		{
			account.draw(drawAmount);
		}
	}
}

 方法二:由于Clock没有隐式的同步监视器,所有要借助Condition

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Account2 {
	//使用lock,没有隐式同步监视器,需要使用condition
	private final Lock lock = new ReentrantLock();
	private final Condition cond = lock.newCondition();
	private String accountNo;
	private double balance;
	private boolean flag = false;
	public Account2(){}
	
	public Account2(String accountNo, double balance)
	{
		this.setAccountNo(accountNo);
		this.setBalance(balance);
	}


	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}
	
	public void draw(double drawAmount)
	{
		lock.lock();
		try
		{
			if(!flag)
			{
				cond.await();
			}
			else
			{
				System.out.println(Thread.currentThread().getName()+"取钱:" + drawAmount);
				balance -= drawAmount;
				System.out.println(Thread.currentThread().getName()+"取钱成功!吐出钞票:"+drawAmount);
				flag = false;
				cond.signalAll();
			}
		}
		catch(InterruptedException ex)
		{
			ex.printStackTrace();
		}
	}
	public synchronized void deposit(double depositeAmount)
	{
		try
		{
			if(flag)
			{
				cond.await();
			}
			else
			{
				System.out.println(Thread.currentThread().getName()+"存款:"+depositeAmount);
				balance += depositeAmount;
				System.out.println("账户余额为:"+ balance);
				flag = true;
				cond.signalAll();
			}
		}
		catch(InterruptedException ex)
		{
			ex.printStackTrace();
		}
		finally
		{
			lock.unlock();
		}
	}

	public String getAccountNo() {
		return accountNo;
	}

	public void setAccountNo(String accountNo) {
		this.accountNo = accountNo;
	}
}

 方法三:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest
{
	public static void main(String[] args)
	{
		BlockingQueue<String> bq = new ArrayBlockingQueue<>(1);
		new Producer(bq).start();
		new Producer(bq).start();
		new Producer(bq).start();
		new Consumer(bq).start();
	}
}

class Producer extends Thread
{
	BlockingQueue<String> bq;
	public Producer(BlockingQueue<String> bq)
	{
		this.bq = bq;
	}
	public void run()
	{
		String[] strArr = {"java", "c", "python"};
		for(int i = 0; i < 100; i ++)
		{
			try
			{
				Thread.sleep(200);
				bq.put(strArr[i%3]);
			}
			catch(InterruptedException ex)
			{
				ex.printStackTrace();
			}
			System.out.println(getName()+"生产者生产元素:"+bq);
		}
	}
}

class Consumer extends Thread
{
	BlockingQueue<String> bq;
	public Consumer(BlockingQueue<String> bq)
	{
		this.bq = bq;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				Thread.sleep(200);
				bq.take();
			}
			catch(InterruptedException ex)
			{
				ex.printStackTrace();
			}
			System.out.println(getName()+"消费者消费完毕。");
		}
	}
}
原文地址:https://www.cnblogs.com/masterlibin/p/5614773.html