多線程通訊就是多個線程同時操作一個資源,但是操作的動作不同
創(chuàng)新互聯(lián)主營興文網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,app開發(fā)定制,興文h5成都微信小程序搭建,興文網(wǎng)站營銷推廣歡迎興文等地區(qū)企業(yè)咨詢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();
}
}
因為上面創(chuàng)建的兩個線程分別是由兩個類創(chuàng)建的,它們的對象不同,所以所對象不同。
那是因為 wait、notify 需要使用到對象鎖,眾所周知,所有全局對象都可以作為對象鎖,而 Object 是所有對象的父類,只要在 Object 實現(xiàn)了 wait、notify,所有類都可以使用到
因為 wait、notify 使用的是對象鎖,所以它們必須放在 synchronize 中使用
wait 阻塞當前執(zhí)行的線程
notify 喚醒鎖池中的線程,使之運行
wait 必須放置在 synchronize 中
join 不需要喚醒
sleep 不需要放在 synchronize 中
sleep 不會釋放鎖
lock 寫法
Lock lock = new ReentrantLock();
lock.lock();
try{
//可能會出現(xiàn)線程安全的操作
} catch(異常){
//處理異常
} finally{
//一定在finally中釋放鎖
//也不能把獲取鎖在try中進行,因為有可能在獲取鎖的時候拋出異常
lock.unlock();
}
Lock 與 Synchronsize 的區(qū)別
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();
}
}
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。