多线程通讯就是多个线程同时操作一个资源,但是操作的动作不同
package com.kernel;
class Res {
private String name;
private String sex;
private Boolean flag;
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 getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
}
class InputThread extends Thread {
private Res res;
public InputThread1(Res res) {
this.res = res;
}
@Override
public void run() {
int count = 0;
while (true) {
synchronized (res) {
if (res.getFlag()) {
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);
res.notify();
}
}
}
}
class OutputThread extends Thread {
private Res res;
public OutputThread1(Res res) {
this.res = res;
}
@Override
public void run() {
while (true)
synchronized (res) {
if (!res.getFlag()) {
try {
res.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(res.getName() + "," + res.getSex());
res.setFlag(false);
res.notify();
}
}
}
public class Test002 {
public static void main(String[] args) {
Res res = new Res();
res.setFlag(false);
InputThread inputThread = new InputThread(res);
OutputThread outputThread = new OutputThread(res);
inputThread.start();
outputThread.start();
}
}
因为上面创建的两个线程分别是由两个类创建的,它们的对象不同,所以所对象不同。
那是因为 wait、notify 需要使用到对象锁,众所周知,所有全局对象都可以作为对象锁,而 Object 是所有对象的父类,只要在 Object 实现了 wait、notify,所有类都可以使用到
因为 wait、notify 使用的是对象锁,所以它们必须放在 synchronize 中使用
wait 阻塞当前执行的线程
notify 唤醒锁池中的线程,使之运行
wait 必须放置在 synchronize 中
join 不需要唤醒
sleep 不需要放在 synchronize 中
sleep 不会释放锁
lock 写法
Lock lock = new ReentrantLock();
lock.lock();
try{
//可能会出现线程安全的操作
} catch(异常){
//处理异常
} finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
lock.unlock();
}
Lock 与 Synchronsize 的区别
Lock 可以非阻塞获得锁,当前线程尝试获取锁,如果锁未被其他线程获取,则成功获得并持有锁
Lock 接口能被中断获取锁,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放
Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回
Condition 用法
Condition 相当于 wait 和 notify 的功能
Condition condition = lock.newCondition();
res. condition.await(); 类似wait
res. Condition. Signal() 类似notify
class Res {
private String name;
private String sex;
private Boolean flag;
Lock lock = new ReentrantLock();
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 getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
}
class InputThread extends Thread {
private Res res;
Condition condition;
public InputThread (Res res, Condition condition) {
this.res = res;
this.condition = condition;
}
@Override
public void run() {
int count = 0;
while (true) {
try {
res.lock.lock();
if (res.getFlag()) {
try {
res.wait();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count == 0) {
res.setName("小红");
res.setSex("女");
} else {
res.setName("小军");
res.setSex("男");
}
count = (count + 1) % 2;
res.setFlag(true);
condition.signal();
} catch (Exception e) {
} finally {
res.lock.unlock();
}
}
}
}
class OutputThread extends Thread {
private Res res;
Condition condition;
public OutputThread (Res res, Condition condition) {
this.res = res;
this.condition = condition;
}
@Override
public void run() {
try {
res.lock.lock();
while (true) {
if (!res.getFlag()) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(res.getName() + "," + res.getSex());
res.setFlag(false);
condition.signal();
}
} catch (Exception e) {
} finally {
res.lock.unlock();
}
}
}
public class Test003 {
public static void main(String[] args) {
Res res = new Res ();
Condition condition = res.lock.newCondition();
res.setFlag(false);
InputThread inputThread = new InputThread(res, condition);
OutputThread outputThread = new OutputThread(res, condition);
inputThread.start();
outputThread.start();
}
}
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。