黑马程序员---Java多线程(2)
来源:互联网 发布:买票软件哪个好知乎 编辑:程序博客网 时间:2024/04/28 08:37
------- android培训、java培训、期待与您交流! ----------
1.当单例模式遇到多线程
单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。
但是如果在多线程并发执行情况下,可能会出现多个实例的现象,解决办法如下:
//懒汉式public class Single2 {private static Single2 s = null;private Single2() {}public static Single2 getInstance() {if (s == null) {synchronized (Single2.class) {if (s == null) {s = new Single2();}}}return s;}}当然对于饿汉式,不存在这个问题;
//饿汉式public class Single {private static final Single s = new Single();private Single(){}public static Single getInstance(){return s;}}
2.多线程间通信(生产者和消费者问题)
如果程序中只有2个线程,一个负责生产,一个负责消费,那么如下就可以解决:
public class Resource {private String name;private String sex;private boolean flag;public synchronized void set(String name, String sex) {if (flag) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}this.name = name;this.sex = sex;flag = true;this.notify();}public synchronized void out() {if (!flag) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println(this.name + " " + this.sex);flag = false;this.notify();}public boolean getFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}}
但是如果有多个生产线程和消费线程的时候,上面的做法就不能正确执行了,还可能会出现死锁的现象。可以采取一下的方式:
public synchronized void set(String name, String sex) {while (flag) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}this.name = name;this.sex = sex;flag = true;this.notifyAll();}public synchronized void out() {while (!flag) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println(this.name + " " + this.sex);flag = false;this.notifyAll();}采用while防止线程被唤醒后不去判断Flag而直接向下执行, 为了保证一定能唤醒需要的线程,采取notifyAll()方式,将线程池中所有被wait的线程都唤醒
但是这样会带来新的难题,如果每次都把所有被wait的线程唤醒,很影响执行效率。
为此在JDK1.5以后,有了新的处理方式:
接口 Lock
Lock
实现提供了比使用synchronized
方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的Condition对象。
Condition
将Object
监视器方法(wait
、notify
和 notifyAll
)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待
set(wait-set)。其中,Lock
替代了synchronized
方法和语句的使用,Condition
替代了 Object 监视器方法的使用。
使用也十分方便,可以改成如下:
public class Res {private String name;private int count = 1;private boolean flag = false;private Lock lock = new ReentrantLock();private Condition pro_con = lock.newCondition();private Condition cum_con = lock.newCondition();public void set(String name) {lock.lock();try {while (flag) {try {pro_con.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}this.name = name + count;count++;System.out.println(Thread.currentThread().getName() + "produce"+ this.name);flag = true;cum_con.signal();} catch (Exception e) {// TODO: handle exception} finally {lock.unlock();}}public void out() {lock.lock();try {while (!flag) {try {cum_con.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println(Thread.currentThread().getName() + "consume"+ this.name);flag = false;pro_con.signal();} catch (Exception e) {// TODO: handle exception} finally {lock.unlock();}}}
在查看JDK时候看到下面代码,对数组的多线程处理,很有思路
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
0 0
- 黑马程序员---Java多线程(2)
- 黑马程序员-java-多线程2
- 黑马程序员--多线程(Java)
- 黑马程序员-java多线程
- 黑马程序员--java 多线程
- 黑马程序员-java多线程
- 黑马程序员--Java多线程
- 黑马程序员--java多线程
- 黑马程序员:Java多线程
- 黑马程序员 Java多线程
- 黑马程序员---Java多线程
- 黑马程序员---多线程【java】
- 黑马程序员----JAVA----多线程---
- 黑马程序员-java多线程
- 黑马程序员-java 多线程
- 黑马程序员-------Java多线程
- 黑马程序员-java多线程
- 黑马程序员-Java多线程
- 页面简单视频设置及播放
- advancedsearch高级搜索 全匹配搜索
- iOS8 Core Image In Swift:更复杂的滤镜
- md5算法 保证下载文件的完整性
- Centos7.0-KDE 启动中文输入法
- 黑马程序员---Java多线程(2)
- Yii-跳转页面-用法(仅限zyd项目)
- 资深程序员生涯自白
- C#构造函数的执行顺序
- 缺陷也是一种美丽
- Flex组件组件添加自定义事件
- C++开学,书籍推荐
- 数字签名原理剖析
- 第k大的数(快速排序的划分过程)