- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个简单的程序来生成 CRC32 的输入,它输出一个以 123456(十六进制)结尾的数字。它在工作线程中进行暴力破解(下一步将是创建多个工作线程)。工作线程将结果发送到队列q
。
import java.util.*;
import java.util.concurrent.*;
import java.util.zip.*;
class A {
static final BlockingQueue<List<Byte>> q =
new LinkedBlockingQueue<List<Byte>>();
static {
new Thread() {
public void run() {
System.out.println("worker thread starting");
int len = 1;
byte[] a = new byte[32];
for (int i =0; i < 32; i++) a[i]=-128;
while (true) {
CRC32 crc = new CRC32();
crc.update(a, 0, len);
long x = crc.getValue();
if ((x & 0xffffff) == 0x123456) {
System.out.println("HA " + Arrays.toString(a) + "; " + x);
List<Byte> l = new LinkedList<Byte>();
for (int i = 0; i < a.length; i++) l.add(a[i]);
System.out.println("A");
q.add(l);
System.out.println("B"); // never reaches here
}
// generate next guess
boolean c = true;
for (int i = 0; i < len && c; i++) {
c = ++a[i] == -128;
if (c) if (i + 2 > len) len = i + 2;
}
}
}
}.start();
}
// for stats: amount of inputs found per interval
static long amount = 3;
static long interval;
static {
// record an initial value for interval, so any code using
// it doesn't have to have a special case to check whether
// it's initialized
long start = System.currentTimeMillis();
while (q.size() != amount);
interval = System.currentTimeMillis() - start;
}
public static void main(String[] args) {
System.out.println("main");
}
}
由于某种原因,它卡住了:
$ javac A.java && java A
worker thread starting
HA [-49, 72, 73, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128]; 1376924758
A
工作线程在发送到队列时明显被阻塞 (q.add(l)
),否则,“B”将被打印到控制台。如果我注释掉从队列中读取的行 (while (q.size() != amount)
),它就不会再卡住。我认为这种行为对于无界队列是不可能的(假设其中还没有 2147483647 个元素)。这不是 SynchronousQueue
,因此无论是否有任何线程正在从中接收数据,发送到队列都应该有效。事实上,这种行为似乎与 SynchronousQueue
相反:只有在没有接收者的情况下才发送。
为什么工作线程在尝试发送到队列时被阻塞?
最佳答案
它在 synchronized(A.class)
而不是队列上被阻塞。
当主线程启动时,它会加载类 A。为此,它会同步类本身以有效地加载类。当您启动一个新线程并尝试访问队列时,它将尝试加载该类(因为该类尚未完成加载,因为第二个静态 block 中的自旋很忙)。现在第一个线程拥有类的同步锁,第二个线程将坐在类监视器上,直到第一个线程存在第二个静态(忙自旋)。
运行程序并kill 3
以查看线程转储。您会注意到类长在类里面而不是队列中。
我将尝试说明这一点。
Thread-1
Load Class A
synchronized(A.class){
static: create new Thread (call it Thread-2)
static: busy spin while (q.size() != amount);
}
Thread-2 (after first static)
run(){
A.q
Load Class A
synchronized(A.class){ //block until Thread-1 releases the lock
A.q.add(..);
}
}
关于java - 除非没有接收者,否则无法发送到无限制的 LinkedBlockingQueue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17408097/
我正在尝试每 60 秒运行一次 CPU 密集型任务。我正在使用带有 PendingIntent 的 AlarmManager,` Intent intent = new Intent(Main
嗨,我正在一个项目中,我使用table_calender创建事件并将其保存在数据库中,我已经成功添加了数据库,然后在数据库中,当我必须检索它们时,当数据库中只有一个事件时,就会出现问题。根据日历显示制
我想构建一个 Sender-Receiver,每个都有两个 PartialView,并通过 Controller 中的发送方法连接它们。 Ajax 操作调用需要必须重新呈现的 div 的 Id。但我希
我目前正在尝试在 UIPickerView.subviews 中找到一个 UIPickerTable ...所以我遍历并执行 isKindOfClass:[UIPickerTable class] .
我正在尝试找到一种解决方案来控制我构建的 Android 应用程序中的 vpn 连接。到目前为止,我可以找到以下结果: 从 Android 版本 2.3.x 开始,无法通过 intents 控制 an
我可以找到大量链接两个调用的示例,但我有 3 个 http 调用使用前一个调用的数据一个接一个地进行。 我有两个人在使用 flatMap 所以: call1(params) .flatMap((r
我是 Azure 服务总线的新手,刚刚按照下面链接中的 MS 指南操作,运行了 2 个 .NET Core 控制台应用程序。一个作为发送者,另一个作为接收者/消费者。 https://learn.mi
我正在尝试从firestore中的flutter中检索单个文档,当存在文档时,它应该返回数据,而当不存在文档时,它应该返回null数据,到目前为止,我尝试过什么: @override Widg
我在使用 Flutter 设置使用电子邮件和密码注册时遇到问题。我让它登录新用户并保存他们的 Firebase 身份验证信息,但它不会将任何配置文件数据保存到 Firebase 存储部分。我不确定我在
我是一名优秀的程序员,十分优秀!