コードコピーは次のとおりです。
パッケージcom.yao;
java.util.concurrent.executorserviceをインポートします。
java.util.concurrent.executorsをインポートします。
java.util.concurrent.futureをインポートします。
java.util.concurrent.locks.lockをインポートします。
java.util.concurrent.locks.readwritelockをインポートします。
java.util.concurrent.locks.reentrantlockをインポートします。
java.util.concurrent.locks.reentrantreadwritelockをインポートします。
/**
*ロッカー
*マルチスレッドプログラミングの重要な概念は、データの整合性を確保するために、複数のスレッドでリソースが共有されている場合です。
*トランザクション操作を実行する場合、共有リソースをロックする必要があります。これにより、トランザクション操作を実行するときに1つのスレッドのみがリソースで動作できるようになります。
*これにより、データの整合性が保証されます。 5.0より前に、ロック関数は同期キーワードによって実装されました。
*/
パブリッククラスロッカー{
/**
*ロックの使用をテストします。メソッドにロックを使用すると、同期されたキーワードの使用を避けることができます。
*/
public static class locktest {
ロックロック= new ReentrantLock(); // lock
double value = 0d;
int addtimes = 0;
/**
*このメソッドの操作は2つのステップに分割され、相互依存しており、トランザクションで実装する必要があります。
*したがって、メソッドを同期する必要があります。以前のプラクティスは、メソッド宣言で同期されたキーワードを使用することでした。
*/
public void addvalue(double v){
lock.lock(); //ロックを取得します
system.out.println( "locktest to addvalue:" + v + ""
+ system.currenttimemillis());
試す {
thread.sleep(1000);
} catch(arternedexception e){
}
this.value += v;
this.addtimes ++;
lock.unlock(); //ロックを解放します
}
public double getValue(){
this.valueを返します。
}
}
public static void testLockTest()スロー例外{
final locktest locktest = new LockTest();
//新しいタスク1を作成し、ロックテストの追加方法を呼び出します
runnable task1 = new runnable(){
public void run(){
locktest.addvalue(55.55);
}
};
//新しいタスク2を作成し、LockTestのGetValueメソッドを呼び出します
runnable task2 = new runnable(){
public void run(){
System.out.println( "value:" + locktest.getValue());
}
};
//新しいタスク実行サービスを作成します
executorservice cachedService = executors.newcachedthreadpool();
Future Future = null;
//タスク1を同時に実行すると、AddValueメソッドはロックメカニズムを使用するため、本質的に順番に実行されます。
for(int i = 0; i <3; i ++){
future = cachedservice.submit(task1);
}
//最後のタスク1が実行されるのを待ちます
future.get();
//タスク2をもう一度実行して結果を出力します
future = cachedservice.submit(task2);
//タスク2が実行されるのを待った後、タスク実行サービスを閉じます
future.get();
cachedservice.shutdownnow();
}
/**
* readwriteLockには2つの内蔵ロックがあり、1つは読み取りロック、もう1つは書面によるロックです。
*複数のスレッドは同時に読み取りロックを取得できますが、書かれたロックを取得できるスレッドは1つだけです。
*書面によるロックがロックされた後、スレッドがロックを取得できません。 readwritelockが提供する方法は次のとおりです。
* readlock():読み取りロックを返します
* writelock():書かれたロックを返します。このロックは排他的です。
* readwriteLockTestは、類似のファイルの読み取り操作を処理するのに非常に適しています。
*読むときは同時に読むことができますが、書くことはできません。
*/
public static class readwritelocktest {
// ロック
readwritelock lock = new ReentrantreadWritelock();
// 価値
double value = 0d;
int addtimes = 0;
/**
*価値の価値を増やし、複数のスレッドが同時にメソッドを入力できるようにしないでください。
*/
public void addvalue(double v){
// writelockとロックを取得します
lock writelock = lock.writeLock();
writelock.lock();
system.out.println( "readwriteLockTest to addValue:" + v + ""
+ system.currenttimemillis());
試す {
thread.sleep(1000);
} catch(arternedexception e){
}
試す {
//執筆作業を行います
this.value += v;
this.addtimes ++;
} ついに {
// Writelockロックを解放します
writelock.unlock();
}
}
/**
*情報を取得します。スレッドがAddValueメソッドを呼び出している場合、getInfoによって取得された情報が正しくない可能性があります。
*したがって、メソッドが呼び出されたときに、メソッドがAddValueメソッドを呼び出されないことを確認する必要があります。
*/
public string getInfo(){
// readlockとロックを取得します
lock readlock = lock.readLock();
readlock.lock();
system.out.println( "readwriteLocktest to getInfo"
+ system.currenttimemillis());
試す {
thread.sleep(1000);
} catch(arternedexception e){
}
試す {
//読書作業を行います
this.value + ":" + this.addtimes;
} ついに {
// readlockをリリースします
readlock.unlock();
}
}
}
public static void testreadwriteLockTest()スロー例外{
final readwritelocktest readwriteLockTest = new ReadWritELockTest();
//新しいタスク1を作成し、ロックテストの追加方法を呼び出します
runnable task_1 = new runnable(){
public void run(){
readwriteLockTest.AddValue(55.55);
}
};
//新しいタスク2を作成し、LockTestのGetValueメソッドを呼び出します
runnable task_2 = new runnable(){
public void run(){
System.out.println( "info:" + readwriteLocktest.getInfo());
}
};
//新しいタスク実行サービスを作成します
executorservice cachedservice_1 = executors.newcachedthreadpool();
Future Future_1 = null;
// 5つのタスクを同時に実行します。最初の2つのタスクはtask_1であり、最後の2つのタスクはtask_2です
for(int i = 0; i <2; i ++){
future_1 = cachedservice_1.submit(task_1);
}
for(int i = 0; i <2; i ++){
future_1 = cachedservice_1.submit(task_2);
}
//最後のタスクはtask_1です
future_1 = cachedservice_1.submit(task_1);
//これらの5つのタスクの実行順序は次のとおりです。
//最初のtask_1が最初に実行され、2番目のtask_1が再度実行されるため、同時に作成できないため、待つ必要があります。
// 2つのtask_2が同時に実行されます。
//同時に読むことができるので、同時に実行されます
//最後のtask_1が再び実行されます。これは、読むときに書くことができないためですので、書くことができる前に読書が終わるまで待つ必要があります。
//最後のtask_2が実行されるのを待ちます
future_1.get();
cachedservice_1.shutdownnow();
}
public static void main(string [] args)スロー例外{
lockers.testlocktest();
System.out.println( "---------------------");
lockers.testreadwritelocktest();
}
}