原子性和易变性2

2020-03-09  本文已影响0人  桐桑入梦
package concurrency;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

class CircularSet{
    private int[] array;
    private int len;
    private int index = 0;

    public CircularSet( int size ){
        array = new int[size];
        len = size;
        for( int i = 0; i < size; i++ )
            array[i] = -1;
    }

    public synchronized void add( int item ){
        array[index] = item;
        index = ++index % len;
    }

    public synchronized boolean contains( int val ){
        for( int i = 0; i < len; i++ ) {
            if( array[i] == val )
                return true;
        }
        return false;
    }
}

public class SerialNumberChecker {
    private static int SIZE = 10;
    private static CircularSet serials = new CircularSet(1000);
    private static ExecutorService exec = Executors.newCachedThreadPool();

    static class SerialChecker implements Runnable{
        @Override
        public void run(){
            while( true ){
                int serial = SerialNumberGenerator.nextSerialNumber();
                if( serials.contains( serial ) ){
                    System.out.println( "Duplicate: " + serial );
                    System.exit( 0 );
                }
                serials.add( serial );
            }
        }
    }

    public static void main(String[] args) throws Exception {
        for( int i = 0; i < SIZE; i++ ){
            exec.execute( new SerialChecker() );
        }

        if( args.length > 0 ){
            TimeUnit.SECONDS.sleep( Integer.parseInt(args[0]) );
            System.out.println( "No duplicates detected" );
            System.exit( 0 );
        }
    }
}

运行的结果:



问题:第一个出现重复数字的线程执行了System.exit( 0 ),那么终止了JVM的运行,为什么会输出那么多的数字?

因为在System.exit( 0 )没有在发现重复数字之后立即执行,导致输出了很多数字。这里使用一个加锁的static方法重写:

package concurrency;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

class CircularSet{
    private int[] array;
    private int len;
    private int index = 0;

    public CircularSet( int size ){
        array = new int[size];
        len = size;
        for( int i = 0; i < size; i++ )
            array[i] = -1;
    }

    public synchronized void add( int item ){
        array[index] = item;
        index = ++index % len;
    }

    public synchronized boolean contains( int val ){
        for( int i = 0; i < len; i++ ) {
            if( array[i] == val )
                return true;
        }
        return false;
    }
}

public class SerialNumberChecker {
    private static int SIZE = 10;
    private static CircularSet serials = new CircularSet(1000);
    private static ExecutorService exec = Executors.newCachedThreadPool();

    static class SerialChecker implements Runnable{
        @Override
        public void run(){
            while( true ){
                int serial = SerialNumberGenerator.nextSerialNumber();
                if( serials.contains( serial ) ){
                    printf( serial );
                }
                serials.add( serial );
            }
        }

        public static synchronized void printf( int serial ){
            System.out.println( "Duplicate: " + serial );
            System.exit( 0 );
        }
    }

    public static void main(String[] args) throws Exception {
        for( int i = 0; i < SIZE; i++ ){
            exec.execute( new SerialChecker() );
        }

        if( args.length > 0 ){
            TimeUnit.SECONDS.sleep( Integer.parseInt(args[0]) );
            System.out.println( "No duplicates detected" );
            System.exit( 0 );
        }
    }
}
期望的运行结果
上一篇 下一篇

猜你喜欢

热点阅读