多线程之间通讯:多个线程操作同一资源,但是操作的方式不同。(比如:一个线程进行读的操作,一个线程进行写的操作)。
代码的实现:
package com.demo;
class Res {
public String name;
public String sex;
}
class InpThread extends Thread {
public Res res;
public InpThread(Res res) {
this.res = res;
}
@Override
public void run() {
int count = 0;
while (true) {
synchronized (res) {//使用synchronized 修饰 是为了解决线程安全问题
if (count == 0) {
res.name = "张三";
res.sex = "男";
} else {
res.name = "李四";
res.sex = "女";
}
count = (count + 1) % 2;
}
}
}
}
class OutThread extends Thread {
public Res res;
public OutThread(Res res) {
this.res = res;
}
@Override
public void run() {
while (true) {
synchronized (res) { //使用synchronized 修饰 是为了解决线程安全问题
System.out.println(res.name + " " + res.sex);
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
Res res = new Res();
InpThread iptThread = new InpThread(res);
iptThread.start();
OutThread outThread = new OutThread(res);
outThread.start();
}
}
wait() 方法:暂定当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行。(同sleep()方法效果一样)。
notify()方法:唤醒锁池中的线程,使之运行。
注意:Wait、Notify一定要在synchronized里面进行使用。
wait 和 sleep 区别:
- sleep方法属于Thread类中,而wait属于Object中。
- 调用sleep方法线程不会释放对象锁,而调用wait方法时,线程会释放对象锁。然后进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备
lock锁用法:
/**
* lock 是一个接口
*
* ReentrantLock(重入锁)
*
* ReadLock/WriteLock 读写锁
*/
Lock lock = new ReentrantLock();
lock.lock();
try{
//可能会出现线程安全的操作
}finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
lock.ublock();
}
//Condition的功能类似于在传统的线程技术中的,Object.wait()和Object.notify()的功能。
Condition condition = lock.newCondition();
res. condition.await(); 类似wait
res. Condition. Signal() 类似notify
class Res {
public String userName;
public String sex;
public boolean flag = false;
Lock lock = new ReentrantLock();
}
class InputThread extends Thread {
private Res res;
Condition newCondition;
public InputThread(Res res, Condition newCondition) {
this.res = res;
this.newCondition=newCondition;
}
@Override
public void run() {
int count = 0;
while (true) {
// synchronized (res) {
try {
res.lock.lock();
if (res.flag) {
try {
// res.wait();
newCondition.await();
} catch (Exception e) {
// TODO: handle exception
}
}
if (count == 0) {
res.userName = "余胜军";
res.sex = "男";
} else {
res.userName = "小红";
res.sex = "女";
}
count = (count + 1) % 2;
res.flag = true;
// res.notify();
newCondition.signal();
} catch (Exception e) {
// TODO: handle exception
}finally {
res.lock.unlock();
}
}
// }
}
}
class OutThrad extends Thread {
private Res res;
private Condition newCondition;
public OutThrad(Res res,Condition newCondition) {
this.res = res;
this.newCondition=newCondition;
}
@Override
public void run() {
while (true) {
// synchronized (res) {
try {
res.lock.lock();
if (!res.flag) {
try {
// res.wait();
newCondition.await();
} catch (Exception e) {
// TODO: handle exception
}
}
System.out.println(res.userName + "," + res.sex);
res.flag = false;
// res.notify();
newCondition.signal();
} catch (Exception e) {
// TODO: handle exception
}finally {
res.lock.unlock();
}
// }
}
}
}
public class ThreadDemo01 {
public static void main(String[] args) {
Res res = new Res();
Condition newCondition = res.lock.newCondition();
InputThread inputThread = new InputThread(res,newCondition);
OutThrad outThrad = new OutThrad(res,newCondition);
inputThread.start();
outThrad.start();
}
}