你有没有想过这种变化对Java编程语言的影响?
String类被设想为一个不可变类(并且这个决定是故意考虑的).但字符串连接真的很慢,我自己对它进行了基准测试.所以StringBuffer诞生了.非常好的课程,同步和非常快.但有些人对某些同步块的性能成本不满意,并引入了StringBuilder.
但是,当使用String来连接不太多的对象时,类的不变性使其成为实现线程安全的一种非常自然的方式.当我们想要管理多个字符串时,我可以理解StringBuffer的使用.但是,这是我的第一个问题:
例如,如果您想要追加10个或更少的字符串,那么您是否会在执行时间内将简单性换成几毫秒?
我也对StringBuilder进行了基准测试.它比StringBuffer更有效(仅提高10%).但是,如果在您的单线程程序中使用StringBuilder,如果您有时想要将设计更改为使用多个线程,会发生什么?你必须改变StringBuilder的每个实例,如果你忘记了一个,你将会产生一些奇怪的效果(考虑到可能出现的竞争条件).
在这种情况下,您会在几小时的调试中交换性能吗?
好的,就是这样.除了简单的问题(StringBuffer比"+"和线程安全更有效,而StringBuilder比StringBuffer更快但没有线程安全)我想知道何时使用它们.
(重要:我知道它们之间的差异;这是与平台架构和一些设计决策相关的问题.)
我有这个简单的测试:
import java.util.Timer;
import java.util.TimerTask;
public class ScheduleTest {
private static long last;
public static void main(String[] args) {
last = System.currentTimeMillis();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println(current - last);
last = current;
}
}, 0, 1000);
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我预期的结果:
0
1000
1000
1000
如果我用ScheduleThreadPoool替换Timer,它会给我一些奇怪的结果:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduleTest {
private static long last;
public static void main(String[] args) {
last = System.currentTimeMillis(); …Run Code Online (Sandbox Code Playgroud) 长期以来,我使用来测量经过时间System.currentTimeMillis(),直到最近才发现我也可以使用nanoTime()。然而,一些结果不是我所期待的,因为nanoTime测量的时间从任意时间点,而不是01-01-1970为currentTimeMillis做。
返回最精确的可用系统计时器的当前值(以纳秒为单位)。
此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示自某个固定但任意时间以来的纳秒 (也许是将来的时间,因此值可能为负)。此方法提供纳秒精度,但不一定提供纳秒精度。不能保证值更改的频率。由于数值溢出,跨越大约292年(263纳秒)的连续呼叫中的差异将无法准确计算经过的时间。
例如,要测量某些代码执行所需的时间:
Run Code Online (Sandbox Code Playgroud)long startTime = System.nanoTime(); // ... the code being measured ... long estimatedTime = System.nanoTime() - startTime;
我对任意部分感到困惑。仅当两个呼叫的参考时间戳相同时,才能测量经过的时间。但是在API文档中不能保证。我认为这就是我提到的问题的原因。使用的时间是实现细节,因此我不能依靠它。
我想知道什么时候可以充分利用,nanoTime在什么情况下会出现严重错误。我想到的主要用例是:
nanoTime来自不同线程的时间戳nanoTime来自同一JVM的不同实例的时间戳(例如,思考,来自先前应用程序运行的序列化时间戳,或作为消息的一部分传递给另一JVM)nanoTime不同JVM实现中的时间戳在StackOverflow上有一些帖子可以解决部分问题,但是很大程度上没有选择时间:
尤其是最后一个链接清楚地表明,何时 nanoTime可以使用存在一些限制,但是在不完全了解这些限制的情况下,使用它似乎本质上是不安全的,因为基于它的功能可能会失败。
如何在 20 秒过去后退出 while 循环?我想避免使用线程。
while (var) {
// ...do something
if (20secondsIsPassed) {
break;
}
}
Run Code Online (Sandbox Code Playgroud) 我希望测量在java中实例化对象所花费的时间.我不能在Eclipse中使用分析工具,因为它不适合我 - 我得到一个讨厌的错误.是否可以手动测量时间?我有以下内容
for (int i=0; i<1000; i++) {
long endTime;
long startTime = System.nanoTime();
MyObj obj = new MyObj();
endTime = System.nanoTime();
System.out.println("Instantiation time: " + (endTime - startTime));
}
Run Code Online (Sandbox Code Playgroud)
然而,问题在于它只是一直返回0.有什么建议?