코드 사본은 다음과 같습니다.
패키지 com.yao;
import java.util.concurrent.executorservice;
java.util.concurrent.executors import;
java.util.concurrent.future import;
java.util.concurrent.locks.lock import;
java.util.concurrent.locks.readwritelock import;
java.util.concurrent.locks.reentrantlock import;
import java.util.concurrent.locks.reentrantreadwritelock;
/**
* 사물함
* 다중 스레드 프로그래밍의 중요한 개념은 데이터의 무결성을 보장하기 위해 리소스가 여러 스레드로 공유되는 경우 잠금됩니다.
* 트랜잭션 운영을 수행 할 때는 공유 리소스를 잠겨 있어야하므로 트랜잭션 운영을 수행 할 때 하나의 스레드 만 리소스에서 작동 할 수 있습니다.
* 이것은 데이터의 무결성을 보장합니다. 5.0 이전에는 잠금 기능이 동기화 된 키워드에 의해 구현되었습니다.
*/
공개 수업 사물함 {
/**
* 잠금 사용을 테스트하십시오. 이 메소드에서 잠금을 사용하면 동기화 된 키워드를 사용하지 않을 수 있습니다.
*/
공개 정적 클래스 잠금 장치 {
잠금 잠금 = 새로운 reintrantlock (); // 잠금
이중 값 = 0D; // 값
int addtimes = 0;
/**
* 값 값을 높이십시오.이 방법의 운영은 2 단계로 나뉘어지고 거래에서 구현되어야합니다.
* 따라서 메소드는 동기화되어야하며, 이전의 사례는 메소드 선언에서 동기화 된 키워드를 사용하는 것이 었습니다.
*/
public void addValue (Double V) {
lock.lock (); // 잠금을 얻습니다
System.out.println ( "AddValue에서 Locktest :" + V + ""
+ System.CurrentTimeMillis ());
노력하다 {
Thread.sleep (1000);
} catch (InterruptedException e) {
}
value += v;
this.addtimes ++;
lock.unlock (); // 잠금을 해제합니다
}
public double getValue () {
이 value를 반환하십시오.
}
}
public static void testlocktest ()는 예외 {
최종 Locktest Locktest = New Locktest ();
// 새 작업 생성 1과 Locktest의 addValue 메소드를 호출하십시오.
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 ();
미래 미래 = null;
// 작업 1을 동시에 3 번 실행합니다. AddValue 메소드는 잠금 메커니즘을 사용하므로 본질적으로 순서대로 실행됩니다.
for (int i = 0; i <3; i ++) {
Future = CachedService.submit (task1);
}
// 마지막 작업 1이 실행될 때까지 기다립니다.
Future.get ();
// 결과를 출력하려면 작업 2를 다시 실행합니다
미래 = CachedService.submit (task2);
// 작업 2가 실행되기를 기다린 후 작업 실행 서비스를 닫습니다.
Future.get ();
CachedService.shutdownnow ();
}
/**
* ReadWritelock에는 두 개의 내장 잠금 장치가 있으며, 하나는 읽기 잠금 장치이고 다른 하나는 서면 잠금 장치입니다.
* 여러 스레드는 동시에 읽기 잠금을 얻을 수 있지만 하나의 스레드 만 작성 잠금을 얻을 수 있습니다.
* 그리고 서면 잠금 장치가 잠긴 후에는 스레드가 잠금을 얻을 수 없습니다. ReadWritelock에서 제공하는 방법은 다음과 같습니다.
* readlock () : 읽기 잠금을 반환합니다
* Writelock () : 서면 잠금을 반환하면이 잠금 장치는 독점적입니다.
* readWritElockTest는 유사한 파일의 읽기 및 쓰기 작업을 처리하는 데 매우 적합합니다.
* 읽을 때 동시에 읽을 수는 있지만, 글을 쓸 수는 없습니다.
*/
공개 정적 클래스 readwritelocktest {
// 잠그다
readwritelock lock = 새로운 ReentrantreadWritelock ();
// 값
이중 값 = 0D;
int addtimes = 0;
/**
* 값 값을 높이고 여러 스레드가 동시에 메소드를 입력하지 않도록하십시오.
*/
public void addValue (Double V) {
// WriteLock을 가져 와서 잠그십시오
잠금 writelock = lock.writelock ();
writelock.lock ();
system.out.println ( "addValue to addValue :" + v + ""
+ System.CurrentTimeMillis ());
노력하다 {
Thread.sleep (1000);
} catch (InterruptedException e) {
}
노력하다 {
// 작문 작업을 수행합니다
value += v;
this.addtimes ++;
} 마지막으로 {
// Writelock 잠금을 해제합니다
writelock.unlock ();
}
}
/**
* 정보를 얻으십시오. 스레드가 addValue 메소드를 호출 할 때 GetInfo가 얻은 정보가 잘못 될 수 있습니다.
* 따라서 메소드가 호출되면 AddValue 메소드를 호출하지 않도록해야합니다.
*/
공개 문자열 getInfo () {
// 레디 락을 가져 와서 잠그십시오
잠금 readlock = lock.readlock ();
readlock.lock ();
system.out.println ( "readwritelocktest to getinfo"
+ System.CurrentTimeMillis ());
노력하다 {
Thread.sleep (1000);
} catch (InterruptedException e) {
}
노력하다 {
// 읽기 작업을 수행합니다
value + ":" + this.addtimes;
} 마지막으로 {
// readlock 릴리스
readlock.unlock ();
}
}
}
public static void testreadwritelocktest ()가 예외 {throws {
최종 readWritElockTest readWritElockTest = new readWritElockTest ();
// 새 작업 생성 1과 Locktest의 addValue 메소드를 호출하십시오.
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 ();
미래 미래 _1 = null;
// 5 개의 작업을 동시에 실행하는데, 그 중 처음 2 개의 작업이 Task_1이고 마지막 두 작업은 Task_2입니다.
for (int i = 0; i <2; i ++) {
future_1 = 캐시드 서비스 _1.submit (task_1);
}
for (int i = 0; i <2; i ++) {
future_1 = 캐시드 서비스 _1.submit (task_2);
}
// 마지막 작업은 Task_1입니다
future_1 = 캐시드 서비스 _1.submit (task_1);
//이 5 가지 작업의 실행 순서는 다음과 같습니다.
// 첫 번째 task_1이 먼저 실행되고 두 번째 task_1이 다시 실행됩니다.
// 그런 다음 두 개의 task_2가 동시에 실행됩니다. 이것은 글을 읽을 수 없으므로 글쓰기가 끝날 때까지 기다립니다.
// 동시에 읽을 수 있기 때문에 동시에 실행됩니다.
// 마지막 task_1이 다시 실행됩니다. 읽을 때 쓸 수 없기 때문에 글을 쓰기 전에 독서가 끝날 때까지 기다려야합니다.
// 마지막 task_2가 실행될 때까지 기다립니다
Future_1.get ();
CachedService_1.ShutdownNow ();
}
public static void main (string [] args)은 예외 {
사물함 .testlocktest ();
System.out.println ( "-------------------------------------------------
Lockers.testReadWritElockTest ();
}
}