Javaスレッドセキュリティの問題-synchronizedロックメカニズム


マルチスレッドテクノロジーを採用したアプリケーションは、システムリソースをよりよく利用できます.その主な利点は、CPUのアイドルタイムスライスを十分に利用し、ユーザーの要求にできるだけ少ない時間で応答することができ、プロセス全体の運行効率を大幅に向上させ、アプリケーションの柔軟性を強化することである.さらに重要なのは、同じプロセスのすべてのスレッドが同じメモリを共有するため、特殊なデータ転送メカニズムを必要とせず、共有ストレージ領域や共有ファイルを構築する必要がなく、異なるタスク間の協調操作と実行、データのインタラクション、リソースの割り当てなどの問題をより容易に解決することができる.
コードが存在するプロセスで複数のスレッドが同時に実行されている場合、これらのスレッドはこのコードを同時に実行する可能性があります.実行結果が単一スレッドで実行されるたびに同じであり、他の変数の値も予想通りであれば、スレッドは安全です.
スレッドセキュリティの問題は、グローバル変数および静的変数によって引き起こされます.
各スレッドの中でグローバル変数、静的変数に対して読み取り操作のみで、書き込み操作がない場合、一般的に、このグローバル変数はスレッドが安全である.複数のスレッドが同時に書き込みを実行する場合は、スレッドの同期を考慮する必要があります.そうしないと、スレッドのセキュリティに影響を与える可能性があります.
スレッドのセキュリティの問題をどのように解決しますか?
Javaのロックメカニズムが必要:synchronized(同期化)スレッド同期:所定の前後順序で実行
例:1.プライマリ・キー・ジェネレータには、クライアントt_が1つずつ追加されます.Clientの値は1増加します.複数のお客様が追加すると、甲が1つ追加すると同時に乙も1つ追加します.この場合、データが間違ったり、追加に成功しなかったりする可能性があります.そのため、同期して実行する必要があります.
public static synchronized int generate(String tableName) {
		String sql = "select value from t_table_id where table_name=? ";
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		int value = 0;
			conn = DbUtil.getConnection();
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, tableName);
			rs = pstmt.executeQuery();
			value = rs.getInt("value");
			value++; //  
			modifyValueField(conn, tableName, value);//      
		return value;
}

       2.マルチスレッドの下で、データベースにアクセスして、資源を十分に利用することができて、大いにアクセスの時間を短縮して、しかしもしすべてデータベースに接続する時すべて1つの接続を作成してすべての接続がプロファイルを読み取るならば、このように大いに浪費して、システムの資源、占有内存はとても大きくて、システムを麻痺させる可能性が高いです.
プロファイルを読み込むにはインスタンスが1つしか必要ありません.多くなると、システムのリソースが浪費されます.
Synchronizedには主に4つの方法があります.
   1. sychronized method(){}
//           ,           :
1.	public synchronized void add(int num) {  
2.	     balance = balance + num;  
3.	}  
4.	public synchronized void withdraw(int num) {  
5.	     balance = balance - num;  
6.	} 

   2. sychronized (objectReference) {/*block*/}
class TreadTest   {
	  public static void main(String[] args)   {
	  	  ThreadB b=new ThreadB();  
	  	  b.start();
	  	  System.out.println("b is start....");
	  	      synchronized(b)
	  	      {  
	  	      	try {
	  	      		  System.out.println("Waiting for b to complete...");
	  	      		    b.wait();
	  	      		      System.out.println("Completed.Now back to main thread");
	  	      		   }catch (InterruptedException e){}
	  	      }
	  	      System.out.println("Total is :"+b.total);  
	  }  
} 
 class ThreadB extends Thread  {
 	  int total;  
 	  public void run()  {
 	  	  synchronized(this)  {
 	  	  	  System.out.println("ThreadB is running..");
 	  	  	  for (int i=0;i<100;i++ )  {
 	  	  	    	  total +=i;  
 	  	  	    	  System.out.println("total is "+total);  
 	  	  	   }  
 	  	  	  notify();  
 	  	  }  
 	  }  
}     

   3. static synchronized method(){}
//         public static synchronized int generate(String tableName) {}

  4. sychronized(classname.class)
 
注:1と2は現在のオブジェクトをロックし、1つのオブジェクトがロックされ、3と4はこのクラスをロックします.つまり、このクラスのロックです.