synchronized (this) { while (true) { //生成大项任务Id majorTaskId = String.valueOf(snowflakeIdGenerator.nextId()); //查看该Id有没有,有就持续生成 int num = sxFloorTaskMapper.selectMajorTaskIdCount(majorTaskId); if(num > 0){ sxFloorTask.setMajorTaskId(majorTaskId);//大项任务Id } } } sxFloorTaskList.add(sxFloorTask); sxFloorTaskList.add(sxFloorTask); 为什么无法访问
时间: 2024-02-14 21:18:37 浏览: 43
这段代码无法被访问的原因是因为它包含一个死循环,这个循环会一直执行下去而不会停止,因此后面的 `sxFloorTaskList.add(sxFloorTask);` 代码也无法被执行。
在这段代码中,synchronized关键字用来保证多个线程同时访问该代码块时的线程安全性。但是,由于while循环条件一直为true,因此程序会一直卡在这里,不会跳出循环,导致后面的代码无法执行。要解决这个问题,需要修改while循环的条件,让它在满足某个条件时可以跳出循环。例如,可以在while循环中加入一个break语句,或者修改while循环的判断条件来控制循环的次数或终止条件。
相关问题
优化这段代码import java.util.Random; public class MyRun04 implements Runnable { public static String[] arr = new String[3]; public MyRun04() { Random r = new Random(); double a= r.nextInt(1,9999)/100; double b=r.nextInt(1,9999-(int)(a*100))/100.0; double c=100-a-b; arr[0]=String.format("%.2f",a); arr[1]=String.format("%.2f",b); arr[2]=String.format("%.2f",c); } public static int count = 3; @Override public void run() { while (true) { synchronized (MyRun04.class) { if (count == 0) { System.out.println(Thread.currentThread().getName() + "没有抢到"); break; } else { count--; System.out.println(Thread.currentThread().getName() + "抢到了" + arr[count] + "元"); break; } } } } }
这段代码已经进行了比较好的优化,但还有一些可以改进的地方。
1. 静态变量count可以改为实例变量,这样更符合面向对象的设计思路。同时,在多线程环境下,需要使用volatile关键字来保证count变量的可见性和原子性。
2. 在run方法中,可以将synchronized关键字加到count变量的修改语句上,这样可以减少锁的范围,提高并发性能。
下面是优化后的代码:
```java
import java.util.Random;
public class MyRun04 implements Runnable {
private static final String[] arr = new String[3];
private volatile int count = 3;
public MyRun04() {
Random r = new Random();
double a = r.nextInt(1, 9999) / 100.0;
double b = r.nextInt(1, 9999 - (int) (a * 100)) / 100.0;
double c = 100 - a - b;
arr[0] = String.format("%.2f", a);
arr[1] = String.format("%.2f", b);
arr[2] = String.format("%.2f", c);
}
@Override
public void run() {
while (true) {
synchronized (this) {
if (count == 0) {
System.out.println(Thread.currentThread().getName() + "没有抢到");
break;
} else {
count--;
System.out.println(Thread.currentThread().getName() + "抢到了" + arr[count] + "元");
break;
}
}
}
}
}
```
优化后的代码中,count变量改为实例变量,并使用volatile关键字修饰,保证了count变量的可见性和原子性。在run方法中,将synchronized关键字加到count变量的修改语句上,减少了锁的范围,提高了并发性能。
Instant now = Instant.now(); // 获取当前时间 long currentTimeMillis = now.toEpochMilli(); // 转换为毫秒值. 三次循环获取的currentTimeMillis数据一致如何解决
`Instant.now()` 是 Java 8 中 `java.time.Instant` 类的一个静态方法,用于获取当前的时间点,它是基于 UTC 的。当你通过 `.toEpochMilli()` 将其转换为自纪元(1970年1月1日 00:00:00 GMT)以来的毫秒数时,理论上应该是实时获取的当前时间。
然而,如果你在三个连续的循环中得到的 `currentTimeMillis` 数据始终一致,这可能是以下几个原因:
1. **线程延迟**:如果这三个操作不是在同一瞬间并行执行的,而是有顺序依赖或者在同一线程中,那么它们会按照相同的顺序执行,结果自然一样。
2. **系统时钟问题**:虽然 `Instant.now()` 应该是最新的时间点,但如果系统的时钟(如网络时钟、本地时钟)存在同步问题,也可能导致两次请求之间的时间差非常小。
3. **代码并发问题**:如果在一个高并发环境中,其他线程对时钟进行了调整,也可能会暂时影响到 `Instant.now()` 返回的时间。
为了解决这个问题,你可以考虑以下策略:
- **强制同步**:如果你确信需要获取绝对最新的时间,可以将这三个操作放在一个锁定的块里,确保它们按顺序执行。
```java
synchronized (this) {
long currentTimeMillis = now.toEpochMilli();
// ...剩下的代码
}
```
- **检查间隔**:如果你关心的是微秒级别的精确度,并且认为系统时钟稳定,可以在多次尝试之后取平均值。
- **使用原子操作**:对于高性能需求,可以利用 `AtomicLong` 或类似原子操作来累积时间戳,然后在循环结束后再求平均。