- 浏览: 67703 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (76)
- Acitviti (5)
- mybatis (4)
- 大数据 (5)
- servlet (1)
- 负载均衡 (1)
- lucene5.X (3)
- mysql (3)
- 数据库 (2)
- Linux (3)
- Java (10)
- SSO (2)
- spring (3)
- layer (1)
- JAVA多线程 (12)
- 设计模式 (1)
- hadoop (6)
- hdfs (2)
- zookeeper (3)
- yarn (1)
- hive (4)
- sqoop (1)
- redis (1)
- GSON (1)
- velocity (1)
- git (1)
- logback (1)
- shell (9)
- IntellJ idea (1)
- JVM (2)
- maven (1)
最新评论
线程直接的通信:通过管道流进行简单的交互
有一个弊端就是在所有的数据写完后才能去读取,这样在写的时候一直占用内存,我们希望每写一点就能拿一点。看下边的实现:
线程直接的通信:使用Thread.yield()模拟一个生产者和消费者的模型
* 效率还是比较差。yield方法是主动放弃了cpu,又去竞争。
yield方法是主动放弃了cpu,又去竞争。效率比较差,接收的人不知道是否send已经Ok了。我们希望我们发送以后就去提醒接收者去拿不是一直去在放弃。
线程直接的通信:wait/notify 任何一个对象都拥有一个线程等待池
* 挂在同一个对象的线程等待池中的线程之间可以互相唤醒 wait/notify是属于Object类的
* wait方法必须放入synchronized同步块中
线程中的通讯:在实际的业务中的使用
一个在处理缓存时候超级实用的例子
public class ThreadDemo6 { public static void main(String[] args) { PipedOutputStream pos=null; PipedInputStream pis=null; try { pos=new PipedOutputStream(); pis=new PipedInputStream(pos); } catch (IOException e) { e.printStackTrace(); } Sender sender=new Sender(pos); Thread t1=new Thread(sender); Receiver receiver=new Receiver(pis); Thread t2=new Thread(receiver); t1.start(); t2.start(); } } class Sender implements Runnable { private OutputStream out; public Sender(OutputStream out) { super(); this.out = out; } @Override public void run() { for (int i = 1; i <= 5; i++) { byte value = (byte) (Math.random() * 100); System.out.println("send value is " + value); try { out.write(value); } catch (IOException e) { e.printStackTrace(); } } } } class Receiver implements Runnable { private InputStream in; public Receiver(InputStream in) { super(); this.in = in; } @Override public void run() { for (int i = 1; i <= 5; i++) { try { byte value = (byte) in.read(); System.out.println("receiver value is " + value); } catch (IOException e) { e.printStackTrace(); } } } }
有一个弊端就是在所有的数据写完后才能去读取,这样在写的时候一直占用内存,我们希望每写一点就能拿一点。看下边的实现:
线程直接的通信:使用Thread.yield()模拟一个生产者和消费者的模型
* 效率还是比较差。yield方法是主动放弃了cpu,又去竞争。
public class ThreadDemo7 { public static void main(String[] args) { FlagSend flagSend = new FlagSend(); FlagRec flagRec = new FlagRec(flagSend); Thread t1 = new Thread(flagSend); Thread t2 = new Thread(flagRec); t1.start(); t2.start(); } } class FlagSend implements Runnable { int theValue; boolean flag;//是否有食物:true有食物 @Override public void run() { for (int i = 1; i <= 5; i++) { while (flag) { Thread.yield(); } theValue = new Random().nextInt(1000);// 制造食物 System.out.println("send value is " + theValue); flag = true;// 等待食客去吃 } } } class FlagRec implements Runnable { public FlagRec(FlagSend flagSend) { super(); this.flagSend = flagSend; } private FlagSend flagSend; @Override public void run() { for (int i = 1; i <= 5; i++) { while (!flagSend.flag) { Thread.yield(); } System.out.println("receiver value is " + flagSend.theValue); flagSend.flag = false; } } }
yield方法是主动放弃了cpu,又去竞争。效率比较差,接收的人不知道是否send已经Ok了。我们希望我们发送以后就去提醒接收者去拿不是一直去在放弃。
线程直接的通信:wait/notify 任何一个对象都拥有一个线程等待池
* 挂在同一个对象的线程等待池中的线程之间可以互相唤醒 wait/notify是属于Object类的
* wait方法必须放入synchronized同步块中
/** * @author Janle * */ public class ThreadDemo8 { public static void main(String[] args) { Cooker cooker=new Cooker(); Diners diners=new Diners(cooker); Thread t1=new Thread(cooker); Thread t2=new Thread(diners); //当程序只有守护线程时候程序退出。 t2.setDaemon(true); t1.start(); t2.start(); } } class Cooker implements Runnable { boolean hasFood; int value; @Override public void run() { for (int i = 1; i <= 5; i++) { // 将锁挂到同一个线程等待池中 synchronized (this) { try { while (hasFood) {// 使用while是因为存在虚假唤醒,不能使用if /** * 在没有被通知、中断或超时的情况下,线程还可以唤醒一个所谓的虚假唤醒 (spurious wakeup)。 * 虽然这种情况在实践中很少发生,但是应用程序必须通过以下方式防止其发生, * 即对应该导致该线程被提醒的条件进行测试, 如果不满足该条件,则继续等待。换句话说,等待应总是发生在循环中 */ this.wait();//wait方法会释放钥匙 } } catch (InterruptedException e) { e.printStackTrace(); } value = new Random().nextInt(1000); System.out.println("Cooker 生产食物 " + value); hasFood=true; this.notify(); } } } } class Diners implements Runnable { private Cooker cooker; public Diners(Cooker cooker) { super(); this.cooker = cooker; } @Override public void run() { for (;;) { // 将锁挂到同一个线程等待池中 synchronized (cooker) { try { while(!cooker.hasFood){ cooker.wait(); } } catch (Exception e) { e.printStackTrace(); } System.out.println("Diners 消费食物 " + cooker.value); cooker.hasFood=false; cooker.notify(); } } } }
线程中的通讯:在实际的业务中的使用
public class ThreadDemo9 { public static void main(String[] args) { final Bussiness bus=new Bussiness(); Thread t1=new Thread(new Runnable() { @Override public void run() { bus.send(); } }); Thread t2=new Thread(new Runnable() { @Override public void run() { bus.recived(); } });t2.setDaemon(true); t1.start(); t2.start(); } } class Bussiness { boolean flag; int value; public void send() { for (int i = 0; i < 5; i++) { synchronized (this) { try { while (flag) { this.wait(); } } catch (Exception e) { e.printStackTrace(); } value = new Random().nextInt(1000); System.out.println("send value is " + value); flag = true; this.notify(); } } } public void recived() { while (true) { synchronized (this) { try { while (!flag) { this.wait(); } } catch (Exception e) { e.printStackTrace(); } System.out.println("receive value is " + value); flag = false; this.notify(); } } } }
一个在处理缓存时候超级实用的例子
/* * @author vayne * * 多线程实现缓存的小demo */ class Cachend { volatile Map<String, String> cachmap = new HashMap<String, String>();//加volatile关键字保证可见性。 ReadWriteLock rwLock = new ReentrantReadWriteLock();//这个读写锁要定义在方法外面,使得每一个线程用的是同一个读写锁。 public String getS(String key) //如果定义在方法内部,就是跟方法栈有关的读写锁。这样可能不是同一个锁。 { rwLock.readLock().lock(); String value = null; try { value = cachmap.get(key); if (cachmap.get(key) == null)//这里要重新获得key对应的value值 { rwLock.readLock().unlock(); rwLock.writeLock().lock(); try { if (cachmap.get(key) == null)//这里也是 { value = "" + Thread.currentThread().getName(); cachmap.put(key, value); System.out.println(Thread.currentThread().getName() + " put the value ::::" + value); } } finally { rwLock.readLock().lock(); //将锁降级,这里跟下一句的顺序不能反。 rwLock.writeLock().unlock();//关于这里的顺序问题,下面我会提到。 } } } finally { rwLock.readLock().unlock(); } return cachmap.get(key); } }
发表评论
-
在多线程使用之ThreadLocal
2017-01-07 19:35 273public class Test { publ ... -
控制线程数量之-Semaphore
2016-12-12 12:15 307使用Semaphore的简单例子 ... -
Callable在多线程合理优化使用
2016-12-02 10:32 2585Future对象在执行使用在 ... -
Java多线程设计
2016-08-12 10:33 775操作系统在运行一个程 ... -
“JUC原子类”之 AtomicLong原子类-02
2016-08-11 10:21 392AtomicLong是作用是对长整 ... -
“JUC原子类”框架-01
2016-08-11 10:08 326根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类。 ... -
使用多线程拆分文件下载
2016-04-13 13:59 594首先我们从任意的一个地方获得资源,考虑到你的带宽创建线程 我们 ... -
多线程死锁问题简单案例
2016-04-08 16:25 459多线程案例其实也就是一句话,我获得一个线程资源不释放,又要获得 ... -
在多线程使用volatile关键字
2016-04-08 16:15 392构建了100个线程, Volati ... -
java线程池
2015-09-09 18:30 306线程执行是好但是线程多了也是会很费空间的所以我们要控制线程的数 ... -
线程范围内数据共享
2015-09-09 16:34 349java实现线程范围内数据共享: Thread.crruntT ...
相关推荐
《POSIX多线程程序设计》深入描述了IEEE的开放系统接口标准——POSIX线程,通常称为Pthreads标准。本书首先解释了线程的基本概念,包括异步编程、线程的生命周期和同步机制;然后讨论了一些高级话题,包括属性对象、...
VC++简单的多线程聊天程序课程设计
Java多线程设计模式,通过对多线程环境的分析,抽象出典型的多线程模型,结合Java编程语言的特性,总结出经典的多线程设计模式,通过本资料的学习,足以让您掌握如何使用JAVA编程技术来解决多线程问题,结合本书实例...
多线程爬虫有道翻译 知识点:多线程爬虫的编写 进程与线程概念 进程 操作系统像是一个奇怪的工厂,因为工人人数有限,每次只能支持一个车间开工。开工运转的车间就是进程,它是操作系统资源调度的单位。 进程与线程...
多线程简单工厂设计模式,工厂方法模式,单列模式,多线程死锁解决
编写一多线程程序,实现如下功能: (1)一个线程进行阶乘和的运算(1!+2!+3!……+30!), 每次阶乘计算时间随机间隔0.5-1秒; (2)另一个线程每隔1秒时间读取上个线程的运算结果和计算 进程,并在图形界面中...
java 多线程 该程序有客户端和服务器端构成,服务器端可以同时有多个客户端请求。 该版本是精简本,读者可以根据自己喜好去不断完善功能。
《JAVA多线程设计模式》PDF 下载 《Java线程 高清晰中文第二版》中文第二版(PDF) 前言 第一章 线程简介 Java术语 线程概述 为什么要使用线程? 总结 第二章 Java线程API 通过Thread类创建线程 使用Runable接口...
Java多线程下载器 使用文件切割技术 适合学习参加比赛 源代码
java一些简单的多线程用法,适合初学者
Linux下支持续传的多线程下载工具的设计与实现.pdf
自己写的简单的多线程聊天程序,程序有很多不足之处,希望大家谅解
基于VC_的多线程聊天程序的设计与实现
简单的web服务器 计算机网络实验 多线程Web服务器的设计与实现
(2)基于Beginthread实现多线程,并实现线程的简单同步。 (3)实现多线程字符串查找程序 Linux: (1)实现多线程字符输出,存在三个线程,线程1用来监听用户输入和其他两个线程的监听器,线程2的主要内容为每隔一...
Java多线程程序设计详细解析: 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。 线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责...
已经实现了多线程按优先权调度,线程间通信,阻塞与唤醒 注释基本齐全,但Readme还没写好
多线程设计 JAVA,写的很简单的,不是很好,还要努力。
主要是练了下写多线程,因此专门设计了多线程,有专门的线程检测连接情况。 ②基于scrcpy实现,可以进一步加强,引入多设备选择功能等。请先进入config.md调整一下配置,默认配置如下。 以下为配置信息 max_fps = ...
java语言,基于socket的多线程一对一聊天,暂不支持并发