一、使用wait()和notify()方法结合实现通信
注意:wait()和notify()必须在synchronized中使用
wait():是当前线程休眠并且释放锁。
notify():唤醒另一个线程
实例:input线程向共享数据中写入一条数据,out线程重共享数据中读一条数据。
/**
* 共享资源对象
* @author Administrator
*
*/
class Res{
private String name;
private String sex;
private boolean flag=false;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public String toString() {
return "Res [name=" + name + ", sex=" + sex + "]";
}
}
/**
* 生产者(写入线程)
* @author Administrator
*
*/
class InputThread extends Thread{
Res res;
int count=0;
public InputThread(Res res) {
this.res=res;
}
@Override
public void run() {
while(true) {
synchronized (res) {
if(res.isFlag()) {
try {
//当前线程进入睡眠
res.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(count==0) {//偶数
res.setName("张三丰");
res.setSex("男");
}else {//奇数
res.setName("李冰冰");
res.setSex("女");
}
//算奇、偶数的
count=(count+1)%2;
//设置标识
res.setFlag(true);
//唤醒out线程
res.notify();
}
}
}
}
/**
* 消费者(输出线程)
* @author Administrator
*
*/
class OutThread extends Thread{
Res res;
public OutThread(Res res) {
this.res=res;
}
@Override
public void run() {
while (true) {
synchronized (res) {
if(!res.isFlag()) {
try {
//当前线程进入睡眠
res.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(res);
res.setFlag(false);
//唤醒input线程
res.notify();
}
}
}
}
public class ThreadCommunication {
public static void main(String[] args) {
Res res=new Res();
InputThread input=new InputThread(res);
OutThread out=new OutThread(res);
input.start();
out.start();
}
}
输出结果为:
Res [name=张三丰, sex=男]
Res [name=李冰冰, sex=女]
Res [name=张三丰, sex=男]
Res [name=李冰冰, sex=女]
Res [name=张三丰, sex=男]
Res [name=李冰冰, sex=女]
Res [name=张三丰, sex=男]
Res [name=李冰冰, sex=女]
Res [name=张三丰, sex=男]
二、使用LOCK锁
使用lock锁的格式为:
Lock lock=new ReentrantLock();
try {
//获取锁
lock.lock();
}catch (Exception e) {
}finally {
//释放锁
lock.unlock();
}
注意:使用lock必须try{}catch(){},释放锁放在finally里面。
使用lock实现上面的例子
/**
* 共享资源对象
* @author Administrator
*
*/
class Res{
private String name;
private String sex;
private boolean flag=false;
private Lock lock=new ReentrantLock();
private Condition condition=lock.newCondition();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public Lock getLock() {
return lock;
}
public void setLock(Lock lock) {
this.lock = lock;
}
public Condition getCondition() {
return condition;
}
public void setCondition(Condition condition) {
this.condition = condition;
}
@Override
public String toString() {
return "Res [name=" + name + ", sex=" + sex + "]";
}
}
/**
* 生产者(写入线程)
* @author Administrator
*
*/
class InputThread extends Thread{
Res res;
int count=0;
public InputThread(Res res) {
this.res=res;
}
@Override
public void run() {
while(true) {
try {
//获取锁
res.getLock().lock();
if(res.isFlag()) {
res.getCondition().await();
}
if(count==0) {
res.setName("张三丰");
res.setSex("男");
}else {
res.setName("李冰冰");
res.setSex("女");
}
count=(count+1)%2;
res.setFlag(true);
//唤醒对方相当于synchronized中用到的notify();
res.getCondition().signal();
}catch (Exception e) {
}finally {
//释放锁
res.getLock().unlock();
}
}
}
}
/**
* 消费者(输出线程)
* @author Administrator
*
*/
class OutThread extends Thread{
Res res;
public OutThread(Res res) {
this.res=res;
}
@Override
public void run() {
while (true) {
try {
//获取锁
res.getLock().lock();;
if(!res.isFlag()) {
res.getCondition().await();
}
System.out.println(res);
res.setFlag(false);
res.getCondition().signal();
}catch (Exception e) {
}finally {
//释放锁
res.getLock().unlock();
}
}
}
}
public class ThreadLock {
public static void main(String[] args) {
Res res=new Res();
InputThread input=new InputThread(res);
OutThread out=new OutThread(res);
input.start();
out.start();
}
}