java - 为什么这段代码运行一段时间后总是什么也不打印?
问题描述
一段时间后我运行 main 方法,它总是什么也不打印。
但是如果我取消注释“System.out.println(111);” 和“System.out.println(222);”,我认为它会正常运行。
我获取了“soldWorker”线程和“refundWorker”线程的转储,他们停在了if
法官面前。
public class ProducerAndConsumer2 {
public static void main(String[] args) {
SyncTikcet2 syncTikcet = new SyncTikcet2(1);
Runnable syncSoldTicket = () -> syncTikcet.soldTicket();
Runnable syncRefundTicket = () -> syncTikcet.refund();
new Thread(syncSoldTicket, "soldWorker").start();
new Thread(syncRefundTicket, "refundWorker").start();
}
}
class SyncTikcet2 {
private Integer ticketNum;
public SyncTikcet2(Integer ticketNum) {
this.ticketNum = ticketNum;
}
public void soldTicket() {
while (true) {
if (ticketNum > 0) {
ticketNum = ticketNum - 1;
System.out.println("sold ticket,the num is" + ticketNum);
} else {
// System.out.println(111);
}
}
}
public void refund() {
while (true) {
if (ticketNum == 0) {
ticketNum = ticketNum + 1;
System.out.println("refund ticket,the num is" + ticketNum);
} else {
// System.out.println(222);
}
}
}
public Integer getTicketNum() {
return ticketNum;
}
public void setTicketNum(Integer ticketNum) {
this.ticketNum = ticketNum;
}
}
解决方案
如果您没有使该字段变为易失性,则线程没有理由重新读取它没有更改的值。
尝试使用private volatile int ticketNum
我建议使用原语 eg int
,除非您必须使用 Object 引用。它不仅更快,而且还清楚地表明您不期望值是null
.
推荐阅读
- c++ - 从十进制转换的二进制中删除前导零
- ruby-on-rails - Heroku Postgres 附加为 HEROKU_POSTGRESQL_COBALT
- tensorflow - 尝试对 Tensorflow Serving Kubernetes pod 进行 gRPC 调用时获取 StatusCode.DEADLINE_EXCEEDED
- google-cloud-platform - GCP 经销商/MSP 能否在其结算报告中看到哪些项目分配给了他的哪些客户?
- javascript - 单击一个按钮时如何打开一个新窗口?
- html - 在特定字符前插入美元符号
- amazon-web-services - 为负载均衡器配置 AWS CPU 利用率指标
- javascript - 错误 [ERR_STREAM_DESTROYED]:在运行电子邮件阅读代码时流被破坏后无法调用 write
- linear-programming - 纸浆包中的整数线性程序生成错误
- git - Git 在远程仓库中只看到 master 分支