[Java 병발] JAVA 병발 프로그래밍 실전. - 독서노트5.
6956 단어 Java 동시 프로그래밍 실전 노트
1, 객체의 상태를 결정하는 변수
2, 제한 상태 변수의 변하지 않는 제약을 확정한다
3, 동시 액세스 객체 상태를 관리하는 정책 수립
데이터를 대상 내부에 봉하여 데이터에 대한 접근을 대상에 제한하는 방법으로 라인이 데이터에 접근할 때 정확한 자물쇠를 얻을 수 있도록 확보하기 쉽다.
public class PersonSer{
private final Set mySer=new HashSet();
public synchronized void addPerson(Person p){
mySet.add(p);
}
public synchronized boolean containsPerson(Person p){
return mySet.contains(p);
}
}
위의 예는 라인이 안전한데 그 중 옳지 않다Person
의 라인 안전성은 어떤 가설을 하든지, 만약 그가 변할 수 있다면, 방문은
PersonSet
에서
Person
추가 동기화가 필요합니다.안전한 사용을 위해서.
Person
대상, 가장 믿을 만한 방법은
Person
자신은 안전하다
Person
모든 사용자가 프로토콜을 준수해야 하기 때문에 대상의 잠금이 믿음직하지 않다.
Person
먼저 정확한 자물쇠를 획득하세요.
public class MonitorVehicleTracker{
private final Map locations;
public MonitorVehicleTracker(Map locations){
this.locations=deepCopy(locations);
}
public synchronized Map getLocations(){
MutablePoint loc=locations.get(id);
return loc==null?null:new MutablePoint(loc);
}
public synchronized void setLoaction(String id,int x,int y){
MutablePoint loc=location.get(id);
if(loc==null){
throw new IllegalArgumentException(“No such ID:”+id);
}
loc.x=x;
loc.y=y;
}
private static Map deepCopy(Map m){
Map result = new HashMap();
for(String id:m.keySet()){
result.put(id,new MutablePoint(m.get(id)));
}
return Collections.unmodifiableMap(result);
}
}
public class MutablePoint{
public int x,y;
public MutablePoint(){
x=0;
y=0;
}
public MutablePoint(MutablePoint p){
this.x=x;
this.y=y;
}
}
사용 가능MutablePoint 대신 Point
public class Point{
public final int x,y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
}
Point 시간은 변할 수 없기 때문에 라인이 안전하기 때문에 우리는 되돌아간다
location
다시는 그들을 복제할 필요가 없다.
ConcurrentHashMap에 스레드 보안 위임
public class DelegatingVehicleTracker{
private final ConcurrentMap locations;
private final Map unmodifiableMap;
public DelegatingVehicleTracker(Map points){
locations=new ConcurrentHashMap(points);
unmodifiableMap=Collections.unmodifiableMap(locations);
}
public Map getLocations(){
return unmodifiableMap;
}
public Point getLocation(String id){
return locations.get(id);
}
public void setLocation(String id,int x,int y){
if(locations.replace(id,new Point(x,y))==null)
throw new IllegalArgumentException(“invalid vehicle name:”+id);
}
}
public class VisualComponent{
private final List keyListeners=new CopyOnWriteArrayList();
private final List mouseListeners=new CopyOnWriteArrayList();
pulic void addKeyListener(KeyListener listener){
keyListeners.add(listener);
}
public void addMouseListener(MouseListener listener){
mouseListeners.add(listener);
}
public void removeKeyListener(KeyListener listener){
keyListeners.remove(listener);
}
public void removeMouseListener(MouseListener listener){
mouseListeners.remove(listener);
}
}
위의 클래스 사용CopyOnWriteArrayList
모든 감청기 목록을 저장합니다.이 라인은 안전해요.
List
오일가스가 감청기 관리에 적합한 명세서를 실현하다.뿐만 아니라
List
한 상태와 다른 상태 간의 결합을 증가시키는 변하지 않는 제약이 없습니다.그러나 대부분의 조합 대상은 위의 클래스처럼 간단하지 않다. 그들의 변하지 않는 제약은 구성 요소의 상태 변수와 서로 연결된다.
public class NumberRange{
private final AtomicInteger lower=new AtomicInteger(0);
private final AtomicInteger upper=new AtomicInteger(0);
public void setLower(int i){
if(i>upper.get()){
throw new IllegalArgumentException();
}
lower.set(i);
}
public void setUpper(int i){
if(ilower.get()&&i<=upper.get());
}
}
위의 클래스는 라인이 안전한 것이 아니다. 두 가지 설정 방법은 변하지 않는 제약을 보호하려고 하지만 적당한 잠금이 없기 때문에 검사를 하고 다시 실행할 때 위험이 존재한다.그리고 발표도 피해야 돼요.
lower
및
upper
사용자가 잠재적으로 변하지 않는 제약을 파괴하는 것을 방지한다.
만약에 하나의 클래스가 서로 독립된 라인 안전 상태 변수로 구성되고 클래스의 조작이 어떠한 무효 상태 전환도 포함하지 않을 때 라인 안전이 이 상태 변수에 위탁된다고 말할 수 있다.
새로운 원자 조작을 추가하는 데는 두 가지 방법이 있는데, 하나는 원시적인 종류를 수정하는 것이다.둘째, 이 종류를 확장한다. 이 종류가 디자인에서 확장할 수 있다고 가정하자.그러나 모든 클래스가 하위 클래스에 충분한 상태를 노출시켜 이런 방안을 지원하는 것은 아니다.확장된 후에 동기화 정책의 실현은 여러 개의 독립적으로 유지보수되는 원본 코드에 분포될 것이다. 만약에 밑에 있는 클래스가 서로 다른 자물쇠를 선택하여 그녀의 상태 변수를 보호하면 그의 동기화 정책이 바뀌고 하위 클래스는 자신도 모르게 파괴된다. 왜냐하면 그는 정확한 자물쇠로 기본 클래스 상태에 대한 병렬 접근을 제어할 수 없기 때문이다.
public class BetterVector extends Vector{
public synchronized boolean putIfAbsent(E x){
boolean absent=!contains(x);
if(absent){
add(x);
}
return absent;
}
}
위의 예는 안전합니다. Vector의 동기화 정책은 규정에 의해 고정되어 있기 때문에 하위 클래스에 문제가 없을 것입니다.
Collections의 경우synchronizedList가 봉인된 ArrayList는 두 가지 방법이 모두 정확하지 않다. 클라이언트 코드는 공장 봉인 방법이 되돌아오는 List 대상의 유형을 동기화할 줄도 모르기 때문이다.세 번째 전략은 확장 기능이지 확장 클래스 자체가 아니라 확장 코드를 조수 클래스에 넣는 것이다.
public class ListHelper{
public List list=Collections.synchronizedList(new ArrayList());
pubic synchronized boolean putIfAbsent(E x){
boolean absent=!list.contains(x);
if(absent){
list.add(x);
}
return absent;
}
}
위의 예는 라인이 안전한 것이 아니다.문제는 동기화 행위가 잘못된 자물쇠에서 발생하는 데 있다.... 을 막론하고List
어떤 자물쇠를 사용하여 그녀의 상태를 보호하면 이 자물쇠가 사용되지 않았는지 확인할 수 있다
ListHelper
올리다
이 방법이 정확하게 작동하도록 하기 위해서, 우리는 방법이 사용하는 자물쇠와List가 클라이언트의 자물쇠와 외부의 자물쇠를 추가할 때 사용하는 자물쇠와 같은 자물쇠를 확보해야 한다.
public class ListHelper{
public List list=Collections.synchronizedList(new ArrayList());
public boolean putIfAbsent(E x){
synchronized(list){
boolean absent=!list.contains(x);
if(absent){
list.add(x);
}
return absent;
}
}
}
위의 클래스 라인은 안전합니다.기존 클래스에 원자 조작을 추가하고 조합을 사용할 수 있습니다.
public class ImprovedList implements List{
private final List list;
public ImprovedList(List list){
this.list=list;
}
public synchronized boolean putIfAbsent(T x){
boolean contains=list.contains(x);
if(contains){
list.add(x);
}
return !contains;
}
public synchronized void clear(){
list.clear();
}
}
내부 잠금을 통해ImprovedList
새로운 자물쇠층을 도입했다.그는 결코 밑바닥에 관심이 없다
List
설령
List
라인이 안전하지 않거나 바뀔 수도 있어요.
ImprovedList
의 잠금 실현,
ImprovedList
자체 호환되는 자물쇠가 있어 라인 안전성을 제공할 수 있지만 일부 성능의 손실은 있을 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Java 병발] JAVA 병발 프로그래밍 실전. - 독서노트10.Executor에서 일괄 처리 작업을 제출하고 싶으면, 결과를 얻으려면 타임아웃이 0인 get을 계속 호출해야 합니다.다행히도 더 좋은 방법이 있다. CompletionServie는 Executor 및 Blockin...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.