a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 110|回复: 0

[专业语言] JAVA认证:JavaThread应注意的技巧

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java的线程编程很是简单。但有时会看到一些关于线程的错误用法。下面列出一些应该注重的问题。. e- ?8 H2 g9 N; a( f1 C
  1.同步对象的恒定性, P: q& u8 ~3 A9 X  t  D
  All java objects are references.( ]3 T. o% k8 ^3 A7 z) I: a$ }
  对于局部变量和参数来说,java琅缦沔的int, float, double, boolean等根基数据类型,都在栈上。这些根基类型是无法同步的;java琅缦沔的对象(根对象是Object),全都在堆里,指向对象的reference在栈上。
! [' v6 _+ B9 b3 |) Q! _1 ]  java中的同步对象,现实上是对于reference所指的“对象地址”进行同步。
' I* b3 D+ o5 U0 ]7 m2 O  需要注重的问题是,万万不要对同步对象年夜头赋值。举个例子。7 ^2 F4 \' [* R' h4 V
  class A implements Runnable
; P  P; f4 N5 \/ J7 h. p  }( J, s2 _# f5 x, u3 N8 b; |
  }
! l7 \5 i8 `1 ^2 e2 q: |# [  f  }3 E- `) i. j1 \  `
  run函数琅缦沔的这段同步代码现实上是毫无意义的。因为每一次lock都给年夜头分配了新的对象的reference,每个线程都在新的reference同步。0 M& m  m' H" n  j
  巨匠可能感受稀疏,怎么会举这么一个例子。因为我见过这样的代码,同步对象在其它的函数里被年夜头赋了新值。
8 c4 U2 V3 l8 T: m/ c4 ]6 d7 F9 ?5 F  这种问题很难查出来。所以,一般应该把同步对象声明为final.3 H/ D! Q& g7 d# \, ~! Z" s
  final Object lock = new Object;+ w, g" X/ P* E! W" }0 ]4 @, I1 }7 k
  使用Singleton Pattern 设计模式来获取同步对象,也是一种很好的选择。
0 s, L# q  q& y$ w7 D1 z% d" a  2.若何放置共享数据
2 A3 P6 M. q) R% F- M# E  实现线程,有两种体例,一种是继续Thread类,一种是实现Runnable接口。
" T  d  y) o. k0 s0 s  膳缦沔举的例子,采用实现Runnable接口的体例。本文举荐这种体例。; z. l' h! ~) l& B2 l
  首先,把需要共享的数据放在一个实现Runnable接口的类琅缦沔,然后,把这个类的实例传给多个Thread的机关体例。这样,新建树的多个Thread,都配合拥有一个Runnable实例,共享统一份数据。
# w/ d2 C" q5 S! V6 z7 A$ ?  假如采用继续Thread类的体例,就只好使用static静态成员了。假如共享的数据斗劲多,就需要年夜量的static静态成员,令轨范数据结构杂乱,难以扩展。这种情形应该尽量避免。' G4 O* w" t" ?# @6 Y: Q
  编写一段多线程代码,措置一个稍微复杂点的问题」现体例的口角,一试便知。; f5 C( F3 c1 K' k4 A4 `; [0 B5 S
  3.同步的粒度
" K% d) O5 T) E7 d! B& q! J! Q  线程同步的粒度越小越好,即,线程同步的代码块越小越好。尽量避免用synchronized润色符来声明体例。尽量使用synchronized的体例,假如不想惹人新的同步对象,使用synchronized的体例。而且,synchronized代码块越小越好。 </p>  public static int maxSubSum3( int [ ] a )
8 ]" m6 n' T- o& j2 i  {
% D+ X6 O. t6 J, X7 s+ m8 D  int maxSum = 0;
$ M# G1 a5 t7 w' A+ n  A  int thisSum = 0;
- H0 O8 C* c/ \: ]) ^  for( int i = 0, j = 0; j < a.length; j++ ). O- }2 R# p: x' r# J0 m% N* w
  {
; e/ Y9 Y2 D/ t( D, ~6 K/ o2 F  thisSum += a[ j ];) y6 h6 y  u9 t3 a. @
  if( thisSum > maxSum )
9 t' M& C* L- X: x) A  {
- Y2 m  |; ~  g* E( R  maxSum = thisSum;7 Z6 G3 b5 q- a  j2 U
  seqStart = i;! z/ k& m. M- u3 s
  seqEnd   = j;
; ]/ u& h! C- z0 j0 S/ I  }; h. m" d  U7 W3 U
  else if( thisSum < 0 )) i; @/ i0 h& c2 b
  {
) Q0 S* A0 }$ }; w  i = j + 1;
; k4 y3 p, B3 h/ R6 {4 o  thisSum = 0;) o; g: e7 ^3 F1 F0 T7 V" G4 G8 n
  }
8 X. r$ s0 U6 c0 ~* f4 Q$ S- W  }# W- F2 L* w% V$ m) Q2 Y6 D- ?
  return maxSum;
3 S% \0 z# z+ L; N" w; v  }
' V8 K( ~, H, C7 c4 e; R  /**# G. A% F) h) T9 }
  * Recursive maximum contiguous subsequence sum algorithm.9 h+ s) Y. n( R  b
  * Finds maximum sum in subarray spanning a[left..right].
8 X( J2 N2 k$ L& N5 I  * Does not attempt to maintain actual best sequence.
* m2 i) Y9 B" o& u  */3 P# k" h: \6 J6 Q  k0 j. Z, E% c
  private static int maxSumRec( int [ ] a, int left, int right )8 H+ ^2 v; M7 G3 d6 X" N+ T* I4 G
  {
0 k# l5 h/ X0 w  |& r  int maxLeftBorderSum = 0, maxRightBorderSum = 0;
1 p% M- j# J. {+ b  int leftBorderSum = 0, rightBorderSum = 0;9 R2 l, Q; b& O% C
  int center = ( left + right ) / 2;* a( G6 H1 x4 P, z2 Y6 N
  if( left == right )  // Base case5 H. }% J0 g* {% R, A- Z
  return a[ left ] > 0 ? a[ left ] : 0;$ q% b0 B; \% C) `# R  E
  int maxLeftSum  = maxSumRec( a, left, center );
: O& w! d! V  ^/ ~+ S7 u  int maxRightSum = maxSumRec( a, center + 1, right );
% o7 ]( i. z* u# u8 y3 m8 Z( F  J4 b  for( int i = center; i >= left; i– )
' r) V# S% z% m# o  {  z3 u2 d+ \6 K( t, R' i$ G
  leftBorderSum += a[ i ];+ A& a+ J( D7 ^3 t; \" _
  if( leftBorderSum > maxLeftBorderSum )/ i6 J1 Y% }' g! V5 A
  maxLeftBorderSum = leftBorderSum;
$ ?7 {) [+ U8 s" A  }
9 h5 w6 S( k, C: C' w  for( int i = center + 1; i  maxRightBorderSum )( I* g% F) O7 v0 a& F
  maxRightBorderSum = rightBorderSum;
3 `+ m/ R2 G% [2 x- O1 C! a( b3 [  }; z& r- S0 E7 M3 T8 u5 W- F
  return max3( maxLeftSum, maxRightSum,
- F! n% H% I6 q0 g( L  maxLeftBorderSum + maxRightBorderSum );$ q' _1 N" Q, T; d. P* Y8 }
  }
& h; m( T% I1 R: o  c7 M /**" W" a6 m# T6 T0 t
  * Return maximum of three integers.
8 |: m9 @8 Y' j6 N& ^. \& X  */6 e+ D0 Y& Z8 G
  private static int max3( int a, int b, int c )
4 G% p$ s/ ~6 u+ @  {# V% M0 q1 t: z) K) g$ |; _( z
  return a > b ? a > c ? a : c : b > c ? b : c;: d7 {' b5 @3 c
  }
  `" t5 ]7 H' c2 m* O3 q  /**3 I' b2 H% o5 k9 |# R3 S" r
  * Driver for divide-and-conquer maximum contiguous
+ }; k+ E5 U3 L. T! g  * subsequence sum algorithm.1 p# l& O  W. q! a$ L' I2 `+ u" a
  */
7 `: y8 \) w# e, s0 ]3 T  public static int maxSubSum4( int [ ] a )# i' N& L, J0 e+ V! ~
  {
, Y1 Q/ o" x4 @9 X  return a.length > 0 ? maxSumRec( a, 0, a.length - 1 ) : 0;% m" L$ [- f1 p" L- I* E
  }! I/ a7 x; |9 u" w) K
  public static void getTimingInfo( int n, int alg )
  e5 h; b; n: `& C$ J( T  Z  {) [  k& E* [: K7 ^: _  B
  int [] test = new int[ n ];
" L2 s$ M* V' b% \' l; e% D9 o  long startTime = System.currentTimeMillis( );;+ E8 S+ E5 ~/ b! j9 _! |0 z9 X7 y
  long totalTime = 0;
% k+ M3 D2 Z( N0 _- `  int i;2 N+ z# a0 ~- A
  for( i = 0; totalTime < 4000; i++ )
. }+ X' p0 J( m+ ?6 o+ C& |  {
- h2 z0 l0 A; s- ]2 m$ w( ]! t9 P  for( int j = 0; j < test.length; j++ )- ^4 L( e5 ^3 N% M, N
  test[ j ] = rand.nextInt( 100 ) - 50;+ c* _5 [- K/ M
  switch( alg )& f% V" I, x6 R" O9 f( Z: o
  {
5 a- U+ Q9 L- ^) t2 W3 c$ C$ Z  case 1:% f: k1 o1 Y- G* A
  maxSubSum1( test );' _; Z! I! t. l  y, s  s! ~
  break;/ d& I$ d4 W6 o% v; h8 `" t
  case 2:
5 \. \5 r/ x7 x, T  maxSubSum2( test );
+ u+ [+ X: ~/ S  break;4 c% c& P+ A3 c) ^4 I; E# i) G
  case 3:
7 ]! d1 N2 j$ p! z5 d  maxSubSum3( test );, b: d; ~4 ?# Z
  break;. D% P* l4 l# p% f5 L7 ?
  case 4:
/ M; k0 o; |9 n# }! Z  maxSubSum4( test );; M, p# p- i5 Y! x% x& Z3 D0 j
  break;  P$ M) E) E. @! R- ^
  }
% I6 k4 W2 ]) a" y  h  totalTime = System.currentTimeMillis( ) - startTime;
# \) S  {! P" i' {$ o  }
: A& O7 \3 E% l  {  System.out.println( ”Algorithm #” + alg + ”t”
: I/ ]; V% {" D; ~9 t8 m  + ”N = ” + test.length
. Z4 e" x! c3 q; r6 t  + ”ttime = ” + ( totalTime * 1000 / i ) + ” microsec” );
3 E# _, D: L; _5 y1 i! v  }8 k) l8 a7 Y0 `* E% X
  private static Random rand = new Random( );
2 u% R6 c- L0 K2 m  /**8 a3 g- t* P& ~
  * Simple test program.! l* ~8 i. b% a. h3 c9 b. v/ r* W
  */9 z& Q6 A3 ]; |% i. S
  public static void main( String [ ] args )
2 \' p1 C+ w) P  E8 T4 G0 n* q1 p0 z  {: \, W1 {8 _! t# G
  int a[ ] = { 4, -3, 5, -2, -1, 2, 6, -2 };5 d$ t7 s6 a( B  U/ C
  int maxSum;5 Q+ P, P! q: B5 l1 u2 i. ?
  maxSum = maxSubSum1( a );; x6 Y: l4 R* I
  System.out.println( ”Max sum is ” + maxSum + ”; it goes”
8 P; s! O# E3 D# |  + ” from ” + seqStart + ” to ” + seqEnd );6 B3 \7 H! r( H5 ~& S# o
  maxSum = maxSubSum2( a );% H9 A1 l# ^+ g" G& G- N  ?2 W( M; Z8 a
  System.out.println( ”Max sum is ” + maxSum + ”; it goes”
$ w" c5 }: X3 g6 }  + ” from ” + seqStart + ” to ” + seqEnd );
$ A! n$ ?! l8 A. D/ j  maxSum = maxSubSum3( a );" }1 W) t; c# e) U% i
  System.out.println( ”Max sum is ” + maxSum + ”; it goes”
# p2 Y5 j1 _7 }8 X+ _  + ” from ” + seqStart + ” to ” + seqEnd );
; `" M2 y& X/ y  maxSum = maxSubSum4( a );& ^3 ~' i( Q7 Y( N6 ?2 F
  System.out.println( ”Max sum is ” + maxSum );4 w; Y5 Y* g3 D
  // Get some timing info
$ r* O9 K# v0 }6 }  for( int n = 10; n = 1; alg– )
2 r4 b$ c5 K- |! r4 O+ ~0 G7 p  {* j6 K5 D2 n( }) ?9 C& U' x
  if( alg == 1 && n > 50000 )
) b0 `+ Z) I' w1 u8 ?- ~  continue;+ x& J8 Z2 i% U# v9 w0 V9 ~  J" m
  getTimingInfo( n, alg );
3 F) V# T  g2 O2 X8 M  }
6 U, I, F6 O+ W, O0 h  }
4 j$ Z  V* q9 H/ _7 F% ?7 A# m  }
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-23 12:26 , Processed in 0.317559 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表