public void run() { while(true) { if (extracted()) { break; private synchronized boolean extracted() { try { sleep(20); } catch (InterruptedException e) { throw new RuntimeException(e); } if (ticket <= 100) { System.out.println(currentThread().getName() + "sale" + ticket); ticket++; } else { //跳出循环并结束线程 return true; } return false; }这样的代码为何会重复卖票 } } }
时间: 2024-02-10 09:19:37 浏览: 144
这段代码实现了一个多线程卖票程序,其中每个线程都会执行该代码块。问题在于,该代码块中的判断语句和卖票语句并不是一个原子操作,即在判断票数是否小于等于100和卖票之间可能会有其他线程进入并卖掉一些票,导致该线程卖重了票。
为了解决这个问题,可以将判断和卖票这两个语句用同步代码块包装起来,即使用synchronized关键字来保证这个代码块的原子性,从而避免多个线程同时执行该代码块。具体实现可以将extracted()方法改为:
private synchronized boolean extracted() {
try {
sleep(20);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (this) {
if (ticket <= 100) {
System.out.println(currentThread().getName() + " sale " + ticket);
ticket++;
} else {
//跳出循环并结束线程
return true;
}
}
return false;
}
这样就可以保证在每个线程执行extracted()方法时,只有一个线程能够进入同步代码块中卖票,从而避免卖重票的问题。
相关问题
帮我看下java代码是否有错,如果有错应该怎么优化: public static void main(String[] args) { Map<String, List<?>> map = new HashMap<>(); extracted(map); } private static List<?> extracted(Map<String, List<?>> map) { List<?> list = new ArrayList<>(); for (Map.Entry<String, List<?>> entry : map.entrySet()) { List<?> value = entry.getValue(); list.addAll(value); } return list; }
我无法确定代码是否有错,但是可以说一些优化建议。你可以考虑使用初始容量更大的HashMap,帮助提升程序性能,并通过使用不可变集合,避免出现潜在的线程安全问题。此外,你还可以考虑使用 Java 8 Streams API 来替换 for 循环,以提高代码的可读性。
Common part can be extracted from 'if'
"Common part"通常是指在代码中可以复用的部分,特别是在条件语句如`if`中。例如,在编程中,我们可能会看到多个相似的`if`结构,它们都检查某个条件并执行相应的操作。提取这些共同部分,我们可以创建一个单独的代码块或者函数,将其作为一个可重用的模块。这样做的好处有:
1. **代码简洁**:减少了重复的代码,使得程序更易于理解和维护。
2. **提高效率**:如果条件判断逻辑复杂,复用可以减少运行时的计算。
3. **增强可维护性**:当需要修改检查条件或关联的操作时,只需在一个地方更新,而不是多个地方。
举个例子,假设我们在一个循环中对数组元素做不同的处理,如果条件匹配,就执行特定操作。提取出这个条件判断的部分,可以形成一个通用的`processIfCondition()`函数:
```python
def processIfCondition(element):
if condition: # 提取出来的条件
perform_action(element) # 具体操作
for item in array:
processIfCondition(item)
```
阅读全文