多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同。 需求:第一个线程写入(input)用户,另一个线程取读取(out)用户,实现写一个,读一个的操作。 代码演示如下: 共享资源实体类 输入线程资源 输出线程 运行代码 运行结果 注意:此时数据会发生错乱,造成线程安全问题 那么解决好线程安全问题,运行结果又会是怎样的呢? 在输入线程InpThread 类中加上synchronized 在输出线程OutThread类中也加上synchronized 那么此时的运行结果是怎样的呢? 注意:InpThread 和 OutThread两个线程同时并行进行,在OutThread线程获取到CPU时会进行多次打印,并不会实现依次打印的效果 那么怎样才能实现依次打印这种效果呢? wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。 使用这三个方法就可以实现线程之间同步,达到了写一个读一个的效果。 代码演示 共享资源实体类 输入线程 输出线程 运行结果 此时线程之间同步,达到了写一个读一个的效果。 因为我们在用多线程进行同步时,锁是由我们自己定义的,为了让所有类都能够使用,所以把wait和notify定义在object类中。 在 jdk1.5 之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,Lock接口提供了与 synchronized 关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。 Lock的写法 Lock 接口与 synchronized 关键字的区别 Condition用法 Condition的功能类似于在传统线程技术中的wait()和notify()的功能 使用Lock同样可以实现上面的效果,代码演示如下: 共享实体资源类 输入线程 输出线程 运行结果 所以使用Lock同样也可以实现上面的效果。1、什么是多线程之间通讯?
2、多线程之间通讯需求
class Res { public String userSex; public String userName; }
class InpThread extends Thread { private Res res; public InpThrad(Res res) { this.res = res; } @Override public void run() { int count = 0; while (true) { if (count == 0) { res.userName = "小明"; res.userSex = "男"; } else { res.userName = "小红"; res.userSex = "女"; } count = (count + 1) % 2; } } }
class OutThread extends Thread { private Res res; public OutThread(Res res) { this.res = res; } @Override public void run() { while (true) { System.out.println(res.userName + "--" + res.userSex); } } }
public static void main(String[] args) { Res res = new Res(); InpThrad inpThrad = new InpThrad(res); OutThread outThread = new OutThread(res); intThrad.start(); outThread.start(); }
class InpThread extends Thread { private Res res; public InpThrad(Res res) { this.res = res; } @Override public void run() { int count = 0; while (true) { synchronized (res) { if (count == 0) { res.userName = "小明"; res.userSex = "男"; } else { res.userName = "小红"; res.userSex = "女"; } count = (count + 1) % 2; } } } }
class OutThread extends Thread { private Res res; public OutThread(Res res) { this.res = res; } @Override public void run() { while (true) { synchronized (res) { System.out.println(res.userName + "--" + res.userSex); } } } }
3、wait()、notify()、notifyAll()方法
class Res { public String userSex; public String userName; //线程通讯标识 public boolean flag = false; }
class InpThrad extends Thread { private Res res; public InpThrad(Res res) { this.res = res; } @Override public void run() { int count = 0; while (true) { synchronized (res) { if (res.flag) { try { // 当前线程变为等待,但是可以释放锁 res.wait(); } catch (Exception e) { // TODO: handle exception } } if (count == 0) { res.userName = "小明"; res.userSex = "男"; } else { res.userName = "小红"; res.userSex = "女"; } count = (count + 1) % 2; res.flag = true; // 唤醒其他等待线程 res.notify(); } } } }
class OutThread extends Thread { private Res res; public OutThread(Res res) { this.res = res; } @Override public void run() { while (true) { synchronized (res) { if (!res.flag) { try { res.wait(); } catch (Exception e) { // TODO: handle exception } } System.out.println(res.userName + "--" + res.userSex); res.flag = false; res.notify(); } } } }
4、 wait与sleep的区别?
5、为什么wait和notify定义在object类中?
6、Lock锁
Lock lock = new ReentrantLock(); lock.lock(); try{ //可能会出现线程安全的操作 }finally{ //一定要在finally中释放锁 lock.unlock(); }
Condition condition = lock.newCondition(); res.condition.await(); //类似于wait res.condition.signal(); //类似于notify
class Res { public String userSex; public String userName; // flag=false时out线程未读取值 public boolean flag = false; // 定义一个锁 Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); }
class InpThread extends Thread { private Res res; public InpThread(Res res) { this.res = res; } @Override public void run() { int count = 0; while (true) { try { res.lock.lock(); if (res.flag) { try { // 当前线程变为等待,但是可以释放锁 // 类似于res.wait(); res.condition.await(); } catch (Exception e) { } } if (count == 0) { res.userName = "小明"; res.userSex = "男"; } else { res.userName = "小红"; res.userSex = "女"; } count = (count + 1) % 2; res.flag = true; // 唤醒当前线程 // 类似于res.notify(); res.condition.signal(); } catch (Exception e) { // TODO: handle exception } finally { res.lock.unlock(); //释放锁,一定要在finally中 } } } }
class OutThread extends Thread { private Res res; public OutThread(Res res) { this.res = res; } @Override public void run() { while (true) { try { res.lock.lock(); if (!res.flag) { try { res.condition.await(); } catch (Exception e) { // TODO: handle exception } } System.out.println(res.userName+"--"+res.userSex); res.flag = false; res.condition.signal(); } catch (Exception e) { } finally { res.lock.unlock(); //释放锁,一定要在finally中 } } } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算