Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用多长时间代替int可以防弹以下方法-有效的Java_Java - Fatal编程技术网

用多长时间代替int可以防弹以下方法-有效的Java

用多长时间代替int可以防弹以下方法-有效的Java,java,Java,考虑以下摘自Joshua Bloch的代码-高效Java,第263页 // Broken - requires synchronization! private static volatile int nextSerialNumber = 0; public static int generateSerialNumber() { return nextSerialNumber++; } 解决问题的一种方法 generateSerialNumber方法用于添加 将同步修改器添加到其 宣言

考虑以下摘自Joshua Bloch的代码-高效Java,第263页

// Broken - requires synchronization!
private static volatile int nextSerialNumber = 0;
public static int generateSerialNumber() {
    return nextSerialNumber++;
}
解决问题的一种方法 generateSerialNumber方法用于添加 将同步修改器添加到其 宣言。这确保 不需要多次调用 交错,并且每次调用 将看到所有以前的 调用。一旦你做到了, 您可以而且应该移除挥发性物质 来自nextSerialNumber的修饰符。到 防弹的方法,使用时间长 而不是int,或引发异常 如果nextSerialNumber即将换行

  • 我知道我们可以在使generateSerialNumber
    同步后删除
    volatile
    ,因为它是冗余的。但是,这有什么害处吗如果我同时拥有同步和易失性(如


  • 用long代替int意味着什么我不明白这种防弹方法是如何实现的?

  • 这仅仅意味着long将容纳比int多得多的数字

    或者在nextSerialNumber即将换行时引发异常

    这意味着这里的问题是,您的数字用完了,最终导致溢出。您希望确保不会发生这种情况。问题是,如果你是一个可能的最大整数,并且你递增,程序不会失败。它不会递增,但结果不再正确

    使用long将推迟这种可能性。抛出异常将表明它已发生

    用long代替int意味着什么


    它确保序列号不会在很长时间内滚动。使用
    int
    可能会用尽所有可用值(因此
    nextSerialNumber
    将具有最大可能的int值),然后在下一个增量时,该值会自动滚动到最小(负)int值,这几乎肯定不是您从序列号中所期望的:-)

    防弹的一种方法是(除上述方法外)

    如果(nextSerialNumber>=整数.MAX_值) //抛出异常


    或者打印出一些内容,或者在调用例程时捕获该异常。在多线程上下文中,volatile/AtomicInteger比synchronized更快。在单线程微基准测试中,它们基本相同。部分原因是synchronized是一个操作系统调用,而volatile完全是用户空间

    我从Java6Update23上的以下程序中得到这个输出

    Average time to synchronized++ 10000000 times. was 110368 us
    Average time to synchronized on the class ++ 10000000 times. was 37140 us
    Average time to volatile++ 10000000 times. was 19660 us
    
    我无法解释为什么类上的同步比普通对象快

    代码:

    静态最终对象o=新对象();
    静态int num=0;
    静态最终AtomicInteger num2=新的AtomicInteger();
    公共静态void main(字符串…参数)抛出InterruptedException{
    最终整数运行=10*1000*1000;
    perfTest(新的Runnable(){
    公开募捐{
    for(int i=0;i
    long
    是64位整数格式,而
    int
    是32位。这些整数类型通常在没有任何警告的情况下溢出-但是溢出
    long
    比溢出
    int
    要花费2^32倍的迭代次数@Jean homial,噢。我认为穿线是防弹的。明白!作者将其添加到一个主要关于合成的段落中,这确实有点让人困惑。是的,同时使用volatile和synchronized可能会对性能造成影响。volatile的性能影响明显小于synchronized。(它也做得更少)谢谢。您是否有关于“如果我同时使用同步和易失性”的答案?应该注意的是,20亿个序列号太多了。如果你每秒产生一个,你就有超过60年的价值。使用
    long
    而不是
    int
    ,即使以每秒一百万次的燃烧速度,你也有足够的时间来覆盖近30万年。即使燃烧速度达到1G/s(祝你好运,很快就能达到这个目标!),你的寿命仍然是目前认为的人类最长寿命的两倍多。让我们在这里有一些观点!事实上,我在一个已有10年历史的遗留应用程序的日志表中看到过这种情况。相信我,你不想成为那个午夜支持电话的人。顺便说一下,我们通过将计数器重置为1来“修复”它。旧数据早就被存档了。@Peter:公平地说,我通常只是随机输入UUID。尽管它很胖,但它的优点是可以跨系统合并ID。我偶尔喜欢暂停一下,感谢我工作在一个我们很少需要担心保存ID的时代
    Average time to synchronized++ 10000000 times. was 110368 us
    Average time to synchronized on the class ++ 10000000 times. was 37140 us
    Average time to volatile++ 10000000 times. was 19660 us
    
    static final Object o = new Object();
    static int num = 0;
    
    static final AtomicInteger num2 = new AtomicInteger();
    
    public static void main(String... args) throws InterruptedException {
        final int runs = 10 * 1000 * 1000;
        perfTest(new Runnable() {
            public void run() {
                for (int i = 0; i < runs; i++)
                    synchronized (o) {
                        num++;
                    }
            }
    
            public String toString() {
                return "synchronized++ " + runs + " times.";
            }
        }, 4);
        perfTest(new Runnable() {
            public void run() {
                for (int i = 0; i < runs; i++)
                    synchronized (Main.class) {
                        num++;
                    }
            }
    
            public String toString() {
                return "synchronized on the class ++ " + runs + " times.";
            }
        }, 4);
        perfTest(new Runnable() {
            public void run() {
                for (int i = 0; i < runs; i++)
                    num2.incrementAndGet();
            }
    
            public String toString() {
                return "volatile++ " + runs + " times.";
            }
        }, 4);
    }
    
    public static void perfTest(Runnable r, int times) throws InterruptedException {
        ExecutorService es = Executors.newFixedThreadPool(times);
        long start = System.nanoTime();
        for (int i = 0; i < times; i++)
            es.submit(r);
        es.shutdown();
        es.awaitTermination(1, TimeUnit.MINUTES);
        long time = System.nanoTime() - start;
        System.out.println("Average time to " + r + " was " + time / times / 10000 + " us");
    }