什么是多线程通讯?

多线程通讯就是多个线程同时操作一个资源,但是操作的动作不同

代码实现

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(); }}为什么在不能使用 this.wait() ?

因为上面创建的两个线程分别是由两个类创建的,它们的对象不同,所以所对象不同。

为什么 wait、notify 属于 Object?

那是因为 wait、notify 需要使用到对象锁,众所周知,所有全局对象都可以作为对象锁,而 Object 是所有对象的父类,只要在 Object 实现了 wait、notify,所有类都可以使用到

wait、notify

因为 wait、notify 使用的是对象锁,所以它们必须放在 synchronize 中使用

wait 阻塞当前执行的线程

notify 唤醒锁池中的线程,使之运行

wait 与 join 的区别

wait 必须放置在 synchronize 中

join 不需要唤醒

wait 与 sleep 的区别

sleep 不需要放在 synchronize 中

sleep 不会释放锁

Lock 锁

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(); }}