- 浏览: 538532 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
飞天奔月:
public List<String> gener ...
实践中的重构30_不做油漆匠 -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道public class A {
...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在世界的中心呼喚愛 写道在classB ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在classB的finalize上打断 ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
iteye比较少上,如果可以的话,可以发e-mail交流:ch ...
深入理解ReferenceQueue GC finalize Reference
今天想做一个System.out的重定向,想要得的结果是有很多个线程写System.out,
利用PipedStread重定向一个JPanel,结果拿到一堆IOException("Write end dead").
看看PipedStream的code,发现里面有些东东值得探讨。
原有的PipedOutputStream和PipedInputStream的工作原理是这样的。
发往PipedOutputStream的byte写到PipedInputStream的一个cache中,基于PipedInputStream
构造一个标准的生产者消费者的锁协议。
查看源代码,有如下问题。
PipedInputStream的connect方法是没有加锁的,PipedOutputStream的connect方法只对PipedOutputStream加锁,
这样当有两个线程同时调用同一个PipedInputStream的connect方法时是有问题的。改啊。
在PipedInputStream里面有Thread readSide和Thread writeSide来分别记录Read thread和write thread.
在每次接收bytes和cache满的时候都要检查readSide,以防止没有reader来读取,这点还是有用的。
但是writeSide的使用导致PipedStream的WriteThread必须在另一个线程读cache的时候为活的。这个也是有一定
意义的,因为pipedStream的doc,已经说明了适用的情况是一个线程写pipe,一个线程读pipe。
但是如果在多个线程写pipe的时候就是一个妨碍了。
看到这里,不是pipedStream不好,是我想要的和pipedStream的spec不吻合。
我想要的是一个可以多个线程写入,单线程读出的Stream对.
利用PipedStread重定向一个JPanel,结果拿到一堆IOException("Write end dead").
看看PipedStream的code,发现里面有些东东值得探讨。
原有的PipedOutputStream和PipedInputStream的工作原理是这样的。
发往PipedOutputStream的byte写到PipedInputStream的一个cache中,基于PipedInputStream
构造一个标准的生产者消费者的锁协议。
查看源代码,有如下问题。
public void connect(PipedOutputStream src) throws IOException { src.connect(this); } public synchronized void connect(PipedInputStream snk) throws IOException { if (snk == null) { throw new NullPointerException(); } else if (sink != null || snk.connected) { throw new IOException("Already connected"); } sink = snk; snk.in = -1; snk.out = 0; snk.connected = true; }
PipedInputStream的connect方法是没有加锁的,PipedOutputStream的connect方法只对PipedOutputStream加锁,
这样当有两个线程同时调用同一个PipedInputStream的connect方法时是有问题的。改啊。
public synchronized void connect(MyPipedInputStream snk) throws IOException { if (snk == null) { throw new NullPointerException(); } if (sink != null) { throw new IOException("Already connected"); } synchronized (snk) { if (snk.connected) { throw new IOException("Already connected"); } sink = snk; snk.in = -1; snk.out = 0; snk.connected = true; } }
在PipedInputStream里面有Thread readSide和Thread writeSide来分别记录Read thread和write thread.
在每次接收bytes和cache满的时候都要检查readSide,以防止没有reader来读取,这点还是有用的。
但是writeSide的使用导致PipedStream的WriteThread必须在另一个线程读cache的时候为活的。这个也是有一定
意义的,因为pipedStream的doc,已经说明了适用的情况是一个线程写pipe,一个线程读pipe。
但是如果在多个线程写pipe的时候就是一个妨碍了。
看到这里,不是pipedStream不好,是我想要的和pipedStream的spec不吻合。
我想要的是一个可以多个线程写入,单线程读出的Stream对.
/** * 多线程写,单线程读的piped stream对. */ public class MyOutputStream extends OutputStream { private MyInputStream sink; private synchronized void connect(MyInputStream snk) throws IOException { if (snk == null) { throw new NullPointerException(); } if (sink != null) { throw new IOException("Already connected"); } synchronized (snk) { if (snk.isConnected()) { throw new IOException("Already connected"); } snk.connect(); sink = snk; } } public MyOutputStream(MyInputStream snk) throws IOException { connect(snk); } @Override public void write(int b) throws IOException { if (sink == null) { throw new IOException("Pipe not connected"); } sink.receive(b); } @Override public void write(byte b[], int off, int len) throws IOException { if (sink == null) { throw new IOException("Pipe not connected"); } sink.receive(b, off, len); } /** * No need to close this stream, the piped stream pair should closed by read * side. */ @Override public void close() { } } /** * 多线程写,单线程读的piped stream对. */ public class MyInputStream extends InputStream { private static final int BUFFER_SIZE = 1024; private byte buffer[] = new byte[BUFFER_SIZE];; private int in = 0; private int out = 0; private int dataLength = 0; private boolean connected = false; private boolean isClosed = false; public MyInputStream() { } private void checkState() throws IOException { if (!connected) { throw new IOException("Pipe not connected."); } if (isClosed) { throw new IOException("Stream is closed."); } } private int readCore() throws IOException { int ret = buffer[out] & 0xFF; if (out < buffer.length - 1) { out++; } else { out = 0; } dataLength--; return ret; } private void receiveCore(int b) throws IOException { buffer[in] = (byte) (b & 0xFF); if (in < buffer.length - 1) { in++; } else { in = 0; } dataLength++; } synchronized private void waitSpace() throws IOException { while (dataLength == buffer.length) { try { notifyAll(); wait(); } catch (InterruptedException e) { throw new InterruptedIOException(); } } } synchronized private void waitData() throws IOException { while (dataLength == 0) { try { notifyAll(); wait(); } catch (InterruptedException e) { throw new InterruptedIOException(); } } } synchronized boolean isConnected() { return connected; } synchronized void connect() { connected = true; } synchronized void receive(int b) throws IOException { checkState(); waitSpace(); receiveCore(b); notifyAll(); } synchronized void receive(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } checkState(); waitSpace(); if (len <= buffer.length - dataLength) { for (int i = off; i < off + len; i++) { receiveCore(b[i]); } notifyAll(); } else { int realTransfer = buffer.length - dataLength; for (int i = off; i < off + realTransfer; i++) { receiveCore(b[i]); } notifyAll(); receive(b, off + realTransfer, len - realTransfer); } } @Override synchronized public int read() throws IOException { checkState(); waitData(); int ret = readCore(); notifyAll(); return ret; } @Override synchronized public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } checkState(); waitData(); int realTransfer = Math.min(dataLength, len); for (int i = off; i < off + realTransfer; i++) { b[i] = (byte) (readCore() & 0xFF); } notifyAll(); return realTransfer; } @Override synchronized public int available() throws IOException { checkState(); return dataLength; } @Override synchronized public void close() { isClosed = true; buffer = null; } /** * n<=Int.Max */ @Override synchronized public long skip(long n) throws IOException { checkState(); if (n <= 0) { return 0; } int realSkip = (int) Math.min(dataLength, n); dataLength = dataLength - realSkip; out = (out + realSkip) % buffer.length; return realSkip; } }
发表评论
-
java对象的大小_基础知识
2014-09-14 16:51 1780引言 Java的对象被jvm管理,单个对象如何布局,大小如何, ... -
xml encoding和实际编码不同导致xml解析异常
2014-04-10 09:52 5014发现一个xml encoding和实际编码不同导致xml解析异 ... -
按照bit读取或写入java的IO流
2012-11-18 22:00 3810写了个按照bit读取或写入java的IO流的简单代码,保留在博 ... -
类构造函数clinit尽量简单化
2012-01-29 16:30 1417java的类构造方法只能执行一次(不考虑多个类加载器和类卸载的 ... -
使用ImageIO.write存储png格式图片性能较差问题
2011-12-27 19:06 29357目前加载一个png格式的图片,做一些绘图工作,发现ImageI ... -
GC iCMS一次调优
2011-12-23 20:00 0原有GC参数: -server -XX:+UseParNew ... -
java集合框架类源代码阅读体会(Java Collections Framework)
2011-09-17 23:55 5038忘了什么原因突然想看下JCF,于是就有了这个阅读体会。 jav ... -
[gc] GC调优及awk脚本分析GC日志
2011-07-20 19:26 2143原有GC参数 JAVA_OPTS="-server ... -
jvm性能查看工具
2011-06-18 11:48 1613jps查看所有java进程。 jconsole jvisu ... -
[gc] java内存管理以及GC
2011-03-27 13:25 4516目录 内存管理简介 GC简介 好的Collector的特性 ... -
object的hash code
2011-01-03 19:40 2135sun的jvm默认的hash code返回的是对象的内部地址构 ... -
Enum简介
2010-08-16 21:51 1525java的Enum不同于c的命名整型常量,它本身是有类型的,而 ... -
java1.5中{@inheritDoc}的使用
2010-07-12 23:14 9610java1.5中@Override还不能用 ... -
[code] 大量只读线程安全的FastHashMap
2010-06-25 17:27 2332org.apache.commons.collections. ... -
[code] 继承TableRowSorter的一个小陷阱
2010-01-09 21:54 1300在一个JTable里面想做sorting。 继承了TableR ... -
深入理解java的finalize
2009-10-11 01:23 19315目录 基本预备相关知 ... -
深入理解java的clone
2009-10-09 14:13 4732目录 预备知识 为什么 ... -
简明OPhone/Android入门体验(有图有源码)
2009-09-25 00:34 3372主要参考 http://code.google.com/p/a ... -
深入理解ReferenceQueue GC finalize Reference
2009-06-22 22:55 20268关于对象如何销毁以及f ...
相关推荐
- **信号量(Semaphore)**:信号量提供了一种更为灵活的同步机制,可以控制多个线程对资源的访问数量。 ```c #include sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); ...
本教程将详细讲解如何使用Python的多线程来实现对多个网址的快速访问,并记录访问结果。 首先,我们需要导入Python的`threading`模块,它是Python标准库中的多线程支持库。`threading.Thread`是创建新线程的类,而`...
父进程可以使用`WaitForSingleObject`或`WaitForMultipleObjects`函数来等待一个或多个线程的结束,并通过`GetExitCodeThread`获取线程的`EXITCODE`。这样,父进程可以根据`EXITCODE`的值来判断子线程的执行情况,...
C#语言提供了对线程的内置支持,通过System.Threading命名空间,我们可以创建和管理线程。Thread类是C#中表示线程的基本类,通过实例化Thread对象并调用其Start方法可以启动新线程。此外,还有ThreadPool类用于管理...
本资源包含六个C#.NET多线程的实例,涵盖了多线程的基本使用到更高级的概念,如线程互斥。以下是这些实例可能涉及的关键知识点: 1. **线程创建**:C#中创建线程主要有两种方式,一是通过`System.Threading.Thread`...
在C#编程中,多线程是一个非常关键的特性,特别是在现代高性能计算和并发操作中。C#提供了丰富的API来支持多线程编程,主要集中在`System.Threading`命名空间下。本篇将深入探讨C#线程相关的知识,并基于描述中的...
在端口扫描中,这可能是为了防止多个线程同时尝试写入扫描结果。 3. **线程池**:为避免频繁创建和销毁线程的开销,可以使用线程池。线程池预先创建一定数量的线程,任务来了就分配给空闲线程,提高了效率。在源码...
多线程并行执行是指在同一个程序中同时运行多个线程,每个线程负责不同的任务,以实现任务的并发执行。这种技术可以充分利用多核处理器的优势,将CPU的计算能力最大化,从而提高程序的运行效率。在Java中,可以通过...
首先,多线程是现代软件开发中的一个重要概念,它允许程序在同一时间执行多个独立的任务。在Halcon中,通过多线程可以并行处理图像,例如,一边进行图像采集,一边进行图像分析,这样可以极大地提高整体处理效率,...
在Delphi编程环境中,多线程控件是一个强大的工具,它允许开发者在单个应用程序中同时执行多个任务,提升程序的效率和响应性。本文将深入探讨Delphi的多线程控件及其应用。 首先,我们需要理解什么是多线程。在...
在IT行业中,多线程技术是一项关键的编程概念,它允许程序同时执行多个任务,显著提高了计算机系统的效率和响应速度。对于大型文件的下载,尤其是网络速度有限的情况下,多线程下载可以将文件分割成若干部分,每个...
对多线程应用的模拟和分析工具要么过于强调单线程应用,要么在执行大型多线程程序时速度过慢。另外,当前的系统架构与支持的应用程序之间存在脱节。 为了在动态二进制插桩系统中支持大型多线程应用程序,Pin团队...
N个线程对完成的A表数据做最后处理 支持大数据量跑批,就是个例子,本来是公司发送促销邮件用的,欢迎提意见和建议。 运行DispatcherMain可以测试,库结构自己可以根据code随便改成父子表关系的就行
C#多线程编程实战7644OT_Code.zip这部分内容可能是该书的配套源码,开发者可以通过阅读和运行这些代码来加深对书本理论的理解。源码是学习多线程的重要实践工具,它可以帮助我们直观地看到线程如何在程序中工作,...
1. **任务分割**:将大文件分成多个小块,每个小块由一个单独的线程负责下载。这样可以充分利用网络带宽,提高下载速度。 2. **并发执行**:多个线程同时工作,下载不同的数据块,有效利用CPU和网络资源。 3. **...
在提供的压缩包文件名称列表`codefans.net`中,可能包含了一个或多个与多线程文件搜索相关的源代码示例。通过分析和学习这些代码,开发者可以深入理解如何在实际项目中应用上述理论知识。 总的来说,多线程的VC++...
线程是操作系统分配CPU时间的基本单位,一个进程可以包含多个线程。在单线程下载中,数据是从服务器到客户端的单一流程。而多线程下载则是将大文件分割成若干小块,每个小块由不同的线程单独下载,然后在客户端进行...
在MFC(Microsoft Foundation ...在实际项目中,你可能还需要考虑多线程安全、流控、错误恢复等高级特性。在`com_write_read`这个文件中,可能包含了相关的示例代码或详细教程,可以帮助你更好地理解和实现这一功能。
多线程能提高程序的响应速度和效率,特别是在进行I/O操作或者CPU密集型任务时,不同线程可以并行处理,避免了单线程的等待时间。 二、Win32 API与线程 Windows API 提供了一套丰富的函数库,用于创建、管理和同步...