会计考友 发表于 2012-8-4 12:44:44

JAVA认证:JavaThread应注意的技巧

Java的线程编程很是简单。但有时会看到一些关于线程的错误用法。下面列出一些应该注重的问题。
  1.同步对象的恒定性
  All java objects are references.
  对于局部变量和参数来说,java琅缦沔的int, float, double, boolean等根基数据类型,都在栈上。这些根基类型是无法同步的;java琅缦沔的对象(根对象是Object),全都在堆里,指向对象的reference在栈上。
  java中的同步对象,现实上是对于reference所指的“对象地址”进行同步。
  需要注重的问题是,万万不要对同步对象年夜头赋值。举个例子。
  class A implements Runnable
  }
  }
  }
  run函数琅缦沔的这段同步代码现实上是毫无意义的。因为每一次lock都给年夜头分配了新的对象的reference,每个线程都在新的reference同步。
  巨匠可能感受稀疏,怎么会举这么一个例子。因为我见过这样的代码,同步对象在其它的函数里被年夜头赋了新值。
  这种问题很难查出来。所以,一般应该把同步对象声明为final.
  final Object lock = new Object;
  使用Singleton Pattern 设计模式来获取同步对象,也是一种很好的选择。
  2.若何放置共享数据
  实现线程,有两种体例,一种是继续Thread类,一种是实现Runnable接口。
  膳缦沔举的例子,采用实现Runnable接口的体例。本文举荐这种体例。
  首先,把需要共享的数据放在一个实现Runnable接口的类琅缦沔,然后,把这个类的实例传给多个Thread的机关体例。这样,新建树的多个Thread,都配合拥有一个Runnable实例,共享统一份数据。
  假如采用继续Thread类的体例,就只好使用static静态成员了。假如共享的数据斗劲多,就需要年夜量的static静态成员,令轨范数据结构杂乱,难以扩展。这种情形应该尽量避免。
  编写一段多线程代码,措置一个稍微复杂点的问题」现体例的口角,一试便知。
  3.同步的粒度
  线程同步的粒度越小越好,即,线程同步的代码块越小越好。尽量避免用synchronized润色符来声明体例。尽量使用synchronized的体例,假如不想惹人新的同步对象,使用synchronized的体例。而且,synchronized代码块越小越好。 </p>  public static int maxSubSum3( int [ ] a )
  {
  int maxSum = 0;
  int thisSum = 0;
  for( int i = 0, j = 0; j < a.length; j++ )
  {
  thisSum += a[ j ];
  if( thisSum > maxSum )
  {
  maxSum = thisSum;
  seqStart = i;
  seqEnd   = j;
  }
  else if( thisSum < 0 )
  {
  i = j + 1;
  thisSum = 0;
  }
  }
  return maxSum;
  }
  /**
  * Recursive maximum contiguous subsequence sum algorithm.
  * Finds maximum sum in subarray spanning a.
  * Does not attempt to maintain actual best sequence.
  */
  private static int maxSumRec( int [ ] a, int left, int right )
  {
  int maxLeftBorderSum = 0, maxRightBorderSum = 0;
  int leftBorderSum = 0, rightBorderSum = 0;
  int center = ( left + right ) / 2;
  if( left == right )// Base case
  return a[ left ] > 0 ? a[ left ] : 0;
  int maxLeftSum= maxSumRec( a, left, center );
  int maxRightSum = maxSumRec( a, center + 1, right );
  for( int i = center; i >= left; i– )
  {
  leftBorderSum += a[ i ];
  if( leftBorderSum > maxLeftBorderSum )
  maxLeftBorderSum = leftBorderSum;
  }
  for( int i = center + 1; imaxRightBorderSum )
  maxRightBorderSum = rightBorderSum;
  }
  return max3( maxLeftSum, maxRightSum,
  maxLeftBorderSum + maxRightBorderSum );
  }
 /**
  * Return maximum of three integers.
  */
  private static int max3( int a, int b, int c )
  {
  return a > b ? a > c ? a : c : b > c ? b : c;
  }
  /**
  * Driver for divide-and-conquer maximum contiguous
  * subsequence sum algorithm.
  */
  public static int maxSubSum4( int [ ] a )
  {
  return a.length > 0 ? maxSumRec( a, 0, a.length - 1 ) : 0;
  }
  public static void getTimingInfo( int n, int alg )
  {
  int [] test = new int[ n ];
  long startTime = System.currentTimeMillis( );;
  long totalTime = 0;
  int i;
  for( i = 0; totalTime < 4000; i++ )
  {
  for( int j = 0; j < test.length; j++ )
  test[ j ] = rand.nextInt( 100 ) - 50;
  switch( alg )
  {
  case 1:
  maxSubSum1( test );
  break;
  case 2:
  maxSubSum2( test );
  break;
  case 3:
  maxSubSum3( test );
  break;
  case 4:
  maxSubSum4( test );
  break;
  }
  totalTime = System.currentTimeMillis( ) - startTime;
  }
  System.out.println( ”Algorithm #” + alg + ”t”
  + ”N = ” + test.length
  + ”ttime = ” + ( totalTime * 1000 / i ) + ” microsec” );
  }
  private static Random rand = new Random( );
  /**
  * Simple test program.
  */
  public static void main( String [ ] args )
  {
  int a[ ] = { 4, -3, 5, -2, -1, 2, 6, -2 };
  int maxSum;
  maxSum = maxSubSum1( a );
  System.out.println( ”Max sum is ” + maxSum + ”; it goes”
  + ” from ” + seqStart + ” to ” + seqEnd );
  maxSum = maxSubSum2( a );
  System.out.println( ”Max sum is ” + maxSum + ”; it goes”
  + ” from ” + seqStart + ” to ” + seqEnd );
  maxSum = maxSubSum3( a );
  System.out.println( ”Max sum is ” + maxSum + ”; it goes”
  + ” from ” + seqStart + ” to ” + seqEnd );
  maxSum = maxSubSum4( a );
  System.out.println( ”Max sum is ” + maxSum );
  // Get some timing info
  for( int n = 10; n = 1; alg– )
  {
  if( alg == 1 && n > 50000 )
  continue;
  getTimingInfo( n, alg );
  }
  }
  }
页: [1]
查看完整版本: JAVA认证:JavaThread应注意的技巧