线程通信
线程通信有三种方法:一是利用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()+"消费者消费完毕。");
}
}
}

浙公网安备 33010602011771号