- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个与 PipedInputStream
相关的问题和 PipedOutputStream
,也不知道是我对这些类的设计有误解,还是PipedInputStream.java
中的java代码有bug
据我了解PipedInputStream
和 PipedOutputStream
实现一种可用于在两个不同线程之间创建流的机制。生产者线程在 PipedOutputStream
中写入了一些内容。消费者线程在连接的 PipedInputStream
中读取它.有一个内部缓冲区以允许缓冲通信。默认情况下,此缓冲区的大小为 1024 字节。
如果消费者线程读取 PipedInputStream
并且缓冲区为空,然后线程等待。如果生产者线程写入 PipedOutputStream
并且缓冲区已满,然后线程也等待。PipedInputStream
维护内部缓冲区,PipedOutputStream
只使用 PipedInputStream
中声明的函数.PipedInputStream
中与内部(循环)缓冲区相关的所有字段( byte [] buffer
、 int in
和 int out
-正如您在 PipedInputStream.java
中看到的那样)都声明为 protected
. PipedInputStream
使用 2 个不同的 PipedInputStream.receive
注入(inject)数据职能。
所有 InputStreams 都有两个读取版本:read()
和 read(byte [], int, int)
.所有的 OutputStreams 都有两个写入版本 write(byte b)
和 write(byte [], int, int)
.都有一个单字节版本和一个多字节版本。 PipedInputStream
和 PipedOutputStream
有这些功能。PipedOutputStream.write(byte b)
使用 PipedInputStream.receive(int b)
在连接的PipedInputStream
中注入(inject)字节的函数.此接收函数声明为 protected
所以你可以重载这个函数并拦截来自PipedOutputStream
的任何字节注入(inject)连接到PipedInputStream
.PipedOutputStream.write(byte b[], int offset, int len)
使用 PipedInputStream.receive(byte [] b, int offset, int len)
在连接的 PipedInputStream
中注入(inject)一个字节数组.
我的问题来了:PipedInputStream.receive(byte [], int, int)
, receive(int)
的多字节对应物, 未被声明为 receive(int)
也就是说,它具有默认的可见性(包可见性)。所以你不能重载这个函数并拦截来自 PipedOutputStream
的多字节注入(inject)。连接到PipedInputStream
.PipedInputStream.write(byte b[], int offset, int len)
不调用 PipedInputStream.write(int b)
.所以重载receive(int)
使用 receive(byte [],int, int)
时无效.
据我了解,PipedInputStream.receive(byte[], int, int)
应该是 protected
如PipedInputStream.receive(int)
是。它的声明:synchronized void receive(byte [] b, int off, int len) throws IOException {
应该:protected synchronized void receive(byte [] b, int off, int len) throws IOException {
PipeReader
和 PipeWriter
(PipedInputStream
和 PipedOutputStream
的字符版本)声明缓冲区字段和具有包可见性的接收方法(不 protected !)。 Java 中的 Reader/Writer(JDK1.1 起)比 InputStream/OutputStream(JDK1.0 起)更新。PipedInputStream
的设计中是否存在真正的错误? ?, 是 protected
PipedInputStream
中的可见度从早期 Java 版本继承的设计事故?还是我完全迷失了?
提前致谢。
PD:这是出现此问题的示例。该程序无法编译(由提到的接收可见性问题)。在这个例子中,我尝试创建一个 PipedInputStream
允许在需要时自动扩展缓冲区的子类。因此,如果缓冲区为空并且有人尝试读取线程等待。但是,如果缓冲区已满并且有人尝试写入(使用连接的 PipedOutputStream
),则线程不会等待,而是扩展缓冲区以存储更多字节。消费者等待,但生产者不等待。
我有自己的这个例子的功能实现,但我想知道它是否不能实现为 PipedInputStream
子类。
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class ExtensiblePipedInputStream extends PipedInputStream {
/**
* Default extensions' size
*/
private static final int DEFAULT_EXTENSION = 1024;
/**
* The current extensions' size
*/
protected int extension = DEFAULT_EXTENSION;
// the same constructors than the super class (PipedInputStream)...
public ExtensiblePipedInputStream() {
super();
}
public ExtensiblePipedInputStream(PipedOutputStream src) throws IOException {
super(src);
}
public ExtensiblePipedInputStream(int pipeSize) {
super(pipeSize);
}
public ExtensiblePipedInputStream(PipedOutputStream src, int pipeSize) throws IOException {
super(src, pipeSize);
}
/**
* This function ensures the specified capacity in the internal buffer. If
* the specified capacity is less or equals than the current internal buffer
* capacity it does nothing. If the specified capacity is greater than the
* current one, then the buffer is extended to: at least allocate the new
* capacity. This function extends the buffer using multiple factors of
* extension size.
*
* @param capacity The capacity
* @throws IOException if an IO error occurs
* @throws IllegalArgumentException if capacity is negative
*/
public synchronized void ensureCapacity(int capacity) throws IOException, IllegalArgumentException {
if (capacity < 0) {
throw new IllegalArgumentException("capacity < 0");
}
if (capacity > buffer.length) {
int additionalSpace = capacity - buffer.length;
final int modExtension = additionalSpace % extension;
additionalSpace += (modExtension == 0) ? 0 : extension - modExtension;
setCapacity(buffer.length + additionalSpace);
}
}
/**
* Returns capacity of the internal buffer (the buffer's size).
*
* @return The capacity or the internal buffer
*/
public synchronized int getCapacity() {
return buffer.length;
}
/**
* Returns the size of the next buffer's extensions.
*
* @return The size of the next buffer's extensions.
*/
public synchronized int getExtension() {
return extension;
}
/**
* This function extends and invokes PipedInputStream.receive. It only avoid
* writers block by extending the internal buffer when needed.
*
* @param b The byte to be received
* @throws IOException if an IO error occurs
*/
@Override
protected synchronized void receive(int b) throws IOException {
ensureCapacity(available() + 1);
super.receive(b);
}
/**
* MY PROBLEM!!!!
*
* this function is not posible!
*
* PipedInputStream.receive(byte[], int, int)
* has not protected visibility, it has package visibility!!!!!
*
* Why?
*
* @param b The array of bytes to be received
* @param off The offset in the array of bytes.
* @param len The number of bytes to be received.
* @throws IOException If an IO error occurs
*/
@Override
protected synchronized void receive(byte b[], int off, int len) throws IOException {
ensureCapacity(available() + len);
super.receive(b, off, len);
}
/**
* Changes the size of the internal buffer. The new size must be greater or
* equals than the number of bytes stored in the internal buffer
* (available())
*
* @param capacity The new size of the internal buffer.
* @throws IOException If an IO error occurs.
* @throws IllegalArgumentException If capacity < available()
*/
public synchronized void setCapacity(int capacity) throws IOException, IllegalArgumentException {
final int available = available();
if (capacity < available) {
throw new IllegalArgumentException("capacity < available");
}
final byte[] nbuf = new byte[capacity];
if (available > 0) {
final int firstTransferAmount = Math.min(available, buffer.length - out);
System.arraycopy(buffer, out, nbuf, 0, firstTransferAmount);
if (in > 0) {
System.arraycopy(buffer, 0, nbuf, firstTransferAmount, in);
}
out = 0;
in = (available == capacity) ? 0 : available;
}
buffer = nbuf;
}
/**
* Set the size of future extensions. It must be a value greater than 0.
*
* @param extension The size of future extensions.
* @throws IllegalArgumentException If extension <= 0
*/
public synchronized void setExtension(int extension) throws IllegalArgumentException {
if (extension <= 0) {
throw new IllegalArgumentException("extension <= 0");
}
this.extension = extension;
}
}
最佳答案
我认为您误解了管道的用途。管道用于 阻塞 两个不同线程之间的通信。写入器的速度预计将受限于读取器的速度,这意味着管道在内存使用方面是有效的,但会将处理限制为最慢组件的速度。
如果您想要异步写入,您应该考虑使用 Queue - java.util.concurrent 包中的版本之一应该适合。
关于java - PipedInputStream.java 的设计中是否存在错误或者我误解了它的设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28364621/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!