System.currentTimeMillis()用法
时间: 2023-11-15 21:45:53 浏览: 320
System.currentTimeMillis()是一个Java系统函数,它的作用是返回当前的系统时间,毫秒为单位。这个函数返回的时间是自1970年1月1日格林威治时间(GMT)0时0分0秒起到当前时间所经过的毫秒数。可以使用这个函数来做以下几个方面的工作:
1. 计算任务耗费的时间:可以使用System.currentTimeMillis()函数在任务开始和结束时分别记录时间,并通过计算两个时间差来计算任务所耗费的毫秒数。
2. 获得当前系统时间:可以使用System.currentTimeMillis()函数获取当前的系统时间,并且可以将其转换为需要的日期格式。
3. 给文件命名:可以使用System.currentTimeMillis()函数生成一个唯一的文件名或者文件路径,避免文件重名的问题。
请注意,System.currentTimeMillis()返回的是一个长整型数值,代表毫秒数。要根据具体需求将其转换为需要的时间格式。
相关问题
private long tilNextMillis(long lastTimestamp) { long timestamp = System.currentTimeMillis(); while (timestamp <= lastTimestamp) { timestamp = System.currentTimeMillis(); } return timestamp; }
<think>好的,我现在需要分析用户的问题。用户之前询问了关于Java中使用雪花ID的内容,现在他进一步询问关于`tilNextMillis`方法的解释。我需要先理解这段代码的作用以及它在整个雪花ID生成器中的位置。
首先,回顾雪花ID的结构,时间戳是其中的重要部分,用来保证ID的趋势递增。在生成ID时,如果同一毫秒内生成的ID超过序列号的最大值(4096),就需要等待到下一毫秒。这时候`tilNextMillis`方法被调用,确保时间戳递增。
用户给出的代码中,`tilNextMillis`方法接收一个`lastTimestamp`参数,然后循环获取当前时间戳,直到当前时间超过`lastTimestamp`。这样做的目的是防止同一毫秒内序列号耗尽,导致ID重复或者等待。
接下来,我需要考虑用户可能的疑问点。比如,为什么需要这个方法?如果没有这个方法会怎样?循环等待是否会影响性能?还有,这个方法在什么情况下会被调用?
然后,我需要用简洁明了的中文解释这个方法的功能、工作原理以及必要性。同时,可能还需要提到时钟回拨的问题,但在这个方法中是否处理了这一点?看起来这个方法主要用于处理序列号耗尽的情况,而时钟回拨是在`nextId`方法中检查的,所以这里可能不需要涉及,但需要明确区分。
另外,用户可能对代码中的位运算和变量移位不太清楚,但在这个问题中,用户直接询问的是`tilNextMillis`方法,所以应聚焦于该方法的具体实现和目的,而不是整个雪花算法的结构。
还需要注意代码中的异常处理,比如在`nextId`方法中如果检测到时间戳回退,会抛出异常,而`tilNextMillis`则是在时间戳相同但序列号用尽时,等待到下一毫秒。需要明确这两个不同情况的处理方式。
最后,总结这个方法的作用,强调其在雪花ID生成中的重要性,确保ID的唯一性和有序性。同时,提醒用户在实际应用中可能需要注意的性能问题,比如高并发下频繁调用此方法是否会导致延迟,但通常由于序列号足够大(12位,4096个),这种情况应该较少出现。</think>#### 方法解析:`tilNextMillis(long lastTimestamp)`
---
##### 1. **功能说明**
此方法用于**解决同一毫秒内序列号耗尽**的问题。当某一毫秒时间内生成的ID数量超过序列号最大值(12位,即$4096$个)时,通过循环等待直到获取新的时间戳(即进入下一毫秒),确保ID的唯一性和递增性。
---
##### 2. **代码逻辑**
```java
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
```
- **输入参数**:`lastTimestamp`(上一次生成ID的时间戳)
- **执行过程**:
1. 获取当前时间戳`timestamp`
2. 循环检查当前时间戳是否小于等于`lastTimestamp`
3. 如果是,则持续获取最新时间戳,直到进入下一毫秒
4. 返回新时间戳
---
##### 3. **核心作用**
- **避免序列号溢出**
当同一毫秒内生成的ID数量达到$4096$(序列号占12位,最大值$2^{12}-1=4095$)时,序列号`sequence`会重置为0。此时必须等待到下一毫秒才能继续生成ID,否则会导致同一毫秒内ID重复。
- **保证时间戳严格递增**
通过强制等待到下一毫秒,确保每次生成ID的时间戳不会“停滞”,维持ID整体趋势递增的特性。
---
##### 4. **调用场景**
在`nextId()`方法中,当检测到当前时间戳与上一次生成ID的时间戳相同时,会尝试自增序列号:
```java
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) { // 序列号溢出(达到4096)
timestamp = tilNextMillis(lastTimestamp); // 等待到下一毫秒
}
}
```
若序列号溢出(`sequence == 0`),则调用`tilNextMillis()`获取新的时间戳。
---
##### 5. **潜在问题与优化**
- **性能影响**
在极端高并发场景下,频繁调用此方法可能导致线程阻塞(需等待1毫秒)。但实际中,每毫秒生成4096个ID已能满足绝大多数需求。
- **时钟回拨无关性**
此方法仅处理序列号溢出问题,时钟回拨问题已在`nextId()`的`if (timestamp < lastTimestamp)`分支单独处理。
---
##### 6. **替代实现**
某些优化方案会改用**线程休眠**避免CPU空转:
```java
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
Thread.sleep(1); // 休眠1毫秒减少CPU消耗
timestamp = System.currentTimeMillis();
}
return timestamp;
}
```
但需注意:休眠可能引入微小延迟,且需处理`InterruptedException`。
---
#### 总结
`tilNextMillis()`是雪花算法中**应对高并发序列号耗尽的核心保障**,通过时间戳等待机制,平衡了ID生成效率与唯一性要求。
system.currenttimemillis方法
system.currenttimemillis方法是Java中的一个系统方法,用于获取当前时间的毫秒数。它返回的是自197年1月1日时分秒(UTC)至今的毫秒数。这个方法常用于计算程序的执行时间,或者在需要精确计时的场合使用。
阅读全文
相关推荐















