您好,登錄后才能下訂單哦!
多線程通訊就是多個線程同時操作一個資源,但是操作的動作不同
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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。