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 );
}
}
}
期望的运行结果
网友评论