同時に一定個数のスレッドを起動するようにする
戻る
::::::::::::::
AbstractService.java
::::::::::::::
/**
* $Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
public abstract class AbstractService {
protected int id;
protected AbstractService( int id ) {
this.id = id;
}
}
::::::::::::::
ContentGatherer.java
::::::::::::::
/**
$Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
*/
import java.io.*;
import java.net.*;
import java.util.*;
public class ContentGatherer {
/** 処理対象URLの文字列 */
private String targetURL;
private URL url;
private long elapsedTime;
private StringBuilder responseBody = null;
private String encoding = null;
private int responseCode = 0;
private List responseHeader = null;
public ContentGatherer( String targetURL, String encoding ) {
this.targetURL = targetURL;
this.encoding = encoding;
}
public void execute() throws Exception {
try {
url = new URL( targetURL );
long start;
long end;
start = System.currentTimeMillis();
//---------------------------------------------------------------
// コネクトして、HttpURLConnection の作成
//---------------------------------------------------------------
HttpURLConnection connection = ( HttpURLConnection ) url.openConnection();
//---------------------------------------------------------------
// ユーザ・エージェントの設定
//---------------------------------------------------------------
String userAgent = RagUtil.sha1Digest( new Date().toString() + "128-256-384-512-640-768" );
if ( ( url.hashCode() + userAgent.hashCode() ) % 2 == 0 ) {
userAgent = userAgent.toUpperCase();
}
connection.setRequestProperty( "User-Agent", userAgent );
// System.err.println( "User-Agent: " + userAgent );
//---------------------------------------------------------------
// キャッシュを使わない
//---------------------------------------------------------------
connection.setUseCaches( false );
//---------------------------------------------------------------
// リダイレクトに対して追従しない設定だが、追従してしまうの使用しない
// connection.setFollowRedirects( false);
// connection.setInstanceFollowRedirects( false);
//---------------------------------------------------------------
//---------------------------------------------------------------
// リクエストメソッドを明示的に指定
//---------------------------------------------------------------
connection.setRequestMethod( "GET" );
//---------------------------------------------------------------
// HTTP応答コードの取得
//---------------------------------------------------------------
responseCode = connection.getResponseCode();
// System.out.println( "コンテントレングスは " + connection.getContentLength() + " です。" );
//---------------------------------------------------------------
// レスポンスヘッダの取得
//---------------------------------------------------------------
ResponseHeaderObtainer obtainer = new ResponseHeaderObtainer( connection );
responseHeader = obtainer.getHeaders();
//---------------------------------------------------------------
// レスポンスボディの取得
//---------------------------------------------------------------
BufferedReader br = new BufferedReader( new InputStreamReader(
connection.getInputStream(), encoding ) );
String line;
responseBody = new StringBuilder();
while ( ( line = br.readLine() ) != null ) {
responseBody.append( line + "\n" );
}
br.close();
//---------------------------------------------------------------
// ディスコネクトする
//---------------------------------------------------------------
connection.disconnect();
end = System.currentTimeMillis();
elapsedTime = ( end - start ) ;
} catch ( Exception exception ) {
throw exception;
}
}
public int getResponseCode() {
return responseCode;
}
public List getResponseHeader() {
return responseHeader;
}
public String getResponseBody() {
return responseBody.toString();
}
public long getElapsedTime() {
return elapsedTime;
}
}
::::::::::::::
RagUtil.java
::::::::::::::
/**
* $Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import java.security.MessageDigest;
public class RagUtil {
/** 文字列からSHA1ハッシュ値を求めて16進で表示する
@param str 入力文字列
@return ハッシュ値
*/
static public String sha1Digest( String str ) {
StringBuffer result = new StringBuffer( "" );
try {
MessageDigest md = MessageDigest.getInstance( "SHA1" ); /* MD5のときは"MD5"とすればいいですよ! */
md.update( str.getBytes() );
byte[] digest = md.digest();
for ( int i = 0; i < digest.length; i++ ) {
if ( ( digest[ i ] & 0x0ff ) / 16 == 0 ) {
result.append( "0" );
}
result.append( Integer.toHexString( digest[ i ] & 0x0ff ) );
}
} catch ( Exception e ) {}
return result.toString();
}
}
::::::::::::::
ResponseHeaderObtainer.java
::::::::::::::
import java.net.*;
import java.io.*;
import java.util.*;
/**
$Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
@author KISHI Yasuhiro
*/
public class ResponseHeaderObtainer {
private HttpURLConnection connection = null;
private List headers = null;
public ResponseHeaderObtainer( HttpURLConnection connection ) throws Exception {
this.connection = connection;
try {
obtain();
} catch ( Exception e ) {
throw e;
}
}
public List getHeaders() {
return headers;
}
private void obtain() throws Exception {
if ( headers == null ) {
headers = new LinkedList();
}
// レスポンスヘッダを読み取る
try {
int n = 1;
String key;
while ( ( key = connection.getHeaderFieldKey( n ) ) != null ) {
String value = connection.getHeaderField( n );
String[] pair = new String[ 2 ];
pair[ 0 ] = key;
pair[ 1 ] = value;
headers.add( pair );
n++;
}
} catch ( Exception e ) {
throw( e );
}
}
}
::::::::::::::
Service.java
::::::::::::::
/**
* $Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
public interface Service {
public void doService();
public int getId();
}
::::::::::::::
ServiceImpl.java
::::::::::::::
/**
* $Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
public class ServiceImpl extends AbstractService implements Service {
private ContentGatherer gatherer = null;
public ServiceImpl( int id ) {
super( id );
}
public void doService() {
/******************************************************************************/
/* 接続タイムアウトの設定; 設定された時間でコネクトできない場合はタイムアウト */
/******************************************************************************/
System.setProperty ( "sun.net.client.defaultConnectTimeout", "10000" );
/**********************************************************************************/
/* 読み取りタイムアウトの設定; 設定された時間で読み取りできない場合はタイムアウト */
/**********************************************************************************/
System.setProperty ( "sun.net.client.defaultReadTimeout", "10000" );
String urlString = "http://www.doblog.com/weblog/myblog/" + id;
try {
gatherer = new ContentGatherer( urlString, "UTF8" );
gatherer.execute();
showStatus();
} catch ( Exception e ) {
e.printStackTrace();
}
}
public synchronized void showStatus() {
System.out.printf( "インデックス: %7s\t" , id );
System.out.print( "応答コード: " + gatherer.getResponseCode() + "\t" );
System.out.print( "所要時間: " + gatherer.getElapsedTime() + " msec\n" );
}
public int getId() {
return id;
}
public static void main( String[] args ) {
Service service = new ServiceImpl( 10 );
service.doService();
}
}
::::::::::::::
ServiceRunnable.java
::::::::::::::
/**
* $Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
import java.util.*;
public class ServiceRunnable implements Runnable {
private Service service = null;
public void setService( Service service ) {
this.service = service;
}
public void run() {
// ビジネス・ロジックの実行
service.doService();
}
}
::::::::::::::
TMain.java
::::::::::::::
/**
* $Id: thread-test.html,v 1.1 2009/06/22 16:12:29 kishi Exp kishi $
* @author KISHI Yasuhiro
* <pre>起動するスレッドの数を制御する</pre>
*/
import java.util.*;
public class TMain {
public static void main( String[] args ) {
// 5個のサービス実行終了を同期させる処理を10回繰り返す
int index = 10000;
for ( int i = 0;i < 10;i++ ) {
Random random = new Random( System.currentTimeMillis() );
long sleepTime = random.nextLong() % 500;
if ( sleepTime < 0 ) {
sleepTime *= -1;
}
try {
System.out.println( sleepTime );
Thread.sleep( sleepTime );
} catch ( Exception e ) {
e.printStackTrace();
}
// Runnableインタフェースを実装したクラスを5個生成
ServiceRunnable[] runnable = new ServiceRunnable[ 5 ];
Thread[] thread = new Thread[ 5 ];
for ( int j = 0;j < 5;j++ ) {
runnable[ j ] = new ServiceRunnable();
runnable[ j ].setService( new ServiceImpl( index++ ) );
thread[ j ] = new Thread( runnable[ j ] );
thread[ j ].start();
}
for ( int j = 0;j < 5;j++ ) {
try {
thread[ j ].join();
} catch ( InterruptedException e ) {
e.printStackTrace();
}
}
System.out.println( "** FINISHED **" );
}
}
}
■実行結果
$ java -cp . TMain
346
インデックス: 10003 応答コード: 200 所要時間: 219 msec
インデックス: 10004 応答コード: 200 所要時間: 375 msec
インデックス: 10002 応答コード: 200 所要時間: 531 msec
インデックス: 10001 応答コード: 200 所要時間: 688 msec
インデックス: 10000 応答コード: 200 所要時間: 1032 msec
** FINISHED **
307
インデックス: 10007 応答コード: 200 所要時間: 15 msec
インデックス: 10008 応答コード: 200 所要時間: 31 msec
インデックス: 10009 応答コード: 200 所要時間: 234 msec
インデックス: 10005 応答コード: 200 所要時間: 391 msec
インデックス: 10006 応答コード: 200 所要時間: 500 msec
** FINISHED **
271
インデックス: 10012 応答コード: 200 所要時間: 94 msec
インデックス: 10013 応答コード: 200 所要時間: 109 msec
インデックス: 10014 応答コード: 200 所要時間: 109 msec
インデックス: 10011 応答コード: 200 所要時間: 594 msec
インデックス: 10010 応答コード: 200 所要時間: 688 msec
** FINISHED **
367
インデックス: 10016 応答コード: 200 所要時間: 15 msec
インデックス: 10019 応答コード: 200 所要時間: 31 msec
インデックス: 10015 応答コード: 200 所要時間: 187 msec
インデックス: 10018 応答コード: 200 所要時間: 656 msec
インデックス: 10017 応答コード: 200 所要時間: 953 msec
** FINISHED **
142
インデックス: 10020 応答コード: 200 所要時間: 47 msec
インデックス: 10022 応答コード: 200 所要時間: 31 msec
インデックス: 10021 応答コード: 200 所要時間: 93 msec
インデックス: 10024 応答コード: 200 所要時間: 93 msec
インデックス: 10023 応答コード: 200 所要時間: 1531 msec
** FINISHED **
60
インデックス: 10028 応答コード: 200 所要時間: 16 msec
インデックス: 10025 応答コード: 200 所要時間: 94 msec
インデックス: 10029 応答コード: 200 所要時間: 94 msec
インデックス: 10026 応答コード: 200 所要時間: 516 msec
インデックス: 10027 応答コード: 200 所要時間: 1531 msec
** FINISHED **
493
インデックス: 10030 応答コード: 200 所要時間: 16 msec
インデックス: 10033 応答コード: 200 所要時間: 31 msec
インデックス: 10034 応答コード: 200 所要時間: 687 msec
インデックス: 10031 応答コード: 200 所要時間: 719 msec
インデックス: 10032 応答コード: 200 所要時間: 953 msec
** FINISHED **
480
インデックス: 10038 応答コード: 200 所要時間: 47 msec
インデックス: 10036 応答コード: 200 所要時間: 109 msec
インデックス: 10035 応答コード: 200 所要時間: 109 msec
インデックス: 10037 応答コード: 200 所要時間: 172 msec
インデックス: 10039 応答コード: 200 所要時間: 750 msec
** FINISHED **
472
インデックス: 10041 応答コード: 200 所要時間: 62 msec
インデックス: 10040 応答コード: 200 所要時間: 125 msec
インデックス: 10042 応答コード: 200 所要時間: 343 msec
インデックス: 10043 応答コード: 200 所要時間: 484 msec
インデックス: 10044 応答コード: 200 所要時間: 812 msec
** FINISHED **
104
インデックス: 10046 応答コード: 200 所要時間: 31 msec
インデックス: 10049 応答コード: 200 所要時間: 16 msec
インデックス: 10045 応答コード: 200 所要時間: 359 msec
インデックス: 10048 応答コード: 200 所要時間: 609 msec
インデックス: 10047 応答コード: 200 所要時間: 796 msec
** FINISHED **
戻る