2012-05-01 2 views
1

내 질문이 질문의보다 구체적인 실체화 : Functional programming: state vs. reassignment자바 : 함수형 프로그래밍에서 스레드 간의 상태를 공유

나는 FP에 newbee 및 Java를 통해 이해하려고 노력 해요.

public class Bank 
{ 
    private double[] accounts = new double[1000]; 

    public synchronized void transfer(int from, int to, double amount) 
    { 
     account[from] -= amount; 
     account[to] += amount; 
    } 
} 

(이것은, 따라서 이러한 검증과 상태 대기 같은 다른 세부 사항을 생략 매우 간단한 예이다)

난 그 목적 여러 스레드간에 공유되는 다음의 클래스가있다.

'전송'방법이 동기화되어 있기 때문에 은행 객체의 가변 상태는 여러 스레드와 공유되어 있어도 손상되지 않습니다. 만약 내가 자바에서 FP를 통해 똑같은 것을 달성하고 싶다면 어떻게 그 코드를 쓸 수 있을까? (실제 코드 예제를보고 싶습니다.)

EDIT : FP에 대한 내 관심은 스레드로부터 안전하고 동시적인 응용 프로그램을 작성할 수 있다는 점에서 비롯됩니다. 다음은 주장하는 기사에 대한 링크입니다. http://www.defmacro.org/ramblings/fp.html

EDIT2 : 방금 Java 용 STM에 대해 알아 냈습니다. 성능에 대해서는 확신 할 수 없지만, 내가 원하는 것을 제공하는 것 같습니다. http://multiverse.codehaus.org/60second.html

+4

"나는 FP에 newbee 해요 자바를 통해 이해하려고 노력"아주 좋은 생각이 아니다 그. http://book.realworldhaskell.org/ –

+0

스레드 안전과 함수 프로그래밍 사이의 연결이 보이지 않습니다. FP를 사용하면 스레드 안전을 달성하기 위해 동기화가 필요하지 않다고 주장하고 있습니까? –

+0

@David Harkness 예. FP를 사용하는 인용 된 이유 중 하나는 (더 동기화 비용은 포함되지 않기 때문에), 따라서 FP는 본질적으로 안전하고 효율적인 스레드 상태에 대한 액세스를 동기화 할 필요가 없습니다, 불변의 상태를 사용하여 해당 인한 패러다임이다; 따라서 멀티 코어 CPU 프로그래밍에 특히 권장됩니다. 참조를 찾고 인용 할 것입니다. – shrini1000

답변

3

공유 된 상태 변수를보다 기능적인 방식으로 접근하는 방법은 여러 가지가 있습니다.

에 당신은 충돌 쓰기에 롤백을 지원하는 프로그램에 정확히 하나 공유 상태 변수를 가지고있다. Haskell에서 이것은 STM 모나드 (트랜잭션 변수를 통해서만 상태를 지원하는 모나드)에 TVar (트랜잭션 변수)을 통해 표현됩니다.

여기서 STM을 사용하면 데드락 방지 기능을 보장 할 수 있다는 장점이 있습니다 (라이브 록은 여전히 ​​가능하지만).

메모리 변수

당신은 또한 MVar의 같은 전통적인 방법을 사용할 수 있습니다. 다음은 잠금 장치로 작동 가변 변수 :

  • 가 스레드 전체 MVAR에 쓰기를, 차단
  • 을 시도하는 경우 값이 제거되거나 변수
  • 에 투입 될 수 있다는 하나 개의 값
  • 를 포함
  • 스레드가 빈 MVAR에서 읽으려고하면 차단이 원자 적으로 공유 값을 업데이트하는 스레드를 지원할 수있는이 방법으로

.

이 가장 관용적이기 때문에 내가의 STM 솔루션을 가고 싶어. 그것은 새로운 세계를 계산하기위한

2

FP는 변경 가능 상태가 아니기 때문에 스레드로부터 안전합니다. 이제 예제에 가변 상태가 포함됩니다.

변경 가능한 상태를 사용하지 않고 원하는 것을 달성 할 수있는 방법을 찾지 못하면 FP 원칙을 적용하여 스레드를 안전하게 만들 수 없습니다.

각 계정에 대해 0부터 시작하여 많은 트랜잭션을 처리하여 처리 된 트랜잭션의 총계 효과를 유지할 수 있습니다. 결국, 모든 액수와 초기 금액을 합산하여 전체 결과를 얻을 수 있습니다.

+0

Thx. FP는 특정 클래스의 문제에만 적용될 수 있으며 변경 가능한 상태를 포함하는 문제에는 직접 적용 할 수 없다는 뜻입니까? – shrini1000

+0

아닙니다. 대부분의 (모든?) 문제는 기능적 패러다임에 맞게 재 공식화 될 수 있습니다. 재구성 된 문제는 메모리와 계산 시간면에서 훨씬 비싸기 때문에 모든 FP 언어는 필요성을 피하기 위해 배열을 포함하여 상태를 변경하는 몇 가지 방법을 가지고 있습니다. – Ingo

1

FP의 개념은 변경 가능한 상태를 피하는 것이며 상태가 필수 일 때 기능 구성을 사용하여 변경 가능성을 시뮬레이션합니다. 예를 들어, 하스켈에서는 monads을 사용하여이를 수행 할 수 있습니다.

+0

+1 모나드에 대한 제안. – shrini1000

+0

그냥 메모 : 당신은 실제로 "시뮬레이션"상태가 아닙니다 - 당신은 정말로 상태 모나드를 사용할 때 상태를 가지고 있습니다. 상태는 기본적으로 허용되지 않으므로 켜야합니다. –

+0

@DonStewart - "시뮬레이션 가능성"을 말했습니다. –

2

기능적 접근 방식으로이 전환에 중요한 것은입니다. 귀하의 예에서 은행 국가는 귀하의 세계이므로 각 TX에 대해 새로운 은행 상태를 계산하려고합니다. 다음과 같이 표시 될 수 있습니다.

그러면 AtomicReference를 사용하여 현재 상태를 보유하고이를 새로운 BankState로 원자 적으로 업데이트 할 수 있습니다.

당신은 오버레이를 필요로하고지도 구현을 계산하지만, 이것들은 아주 쉽게 예를 들어 구아바를 사용하여 만든 것 (이미 MapMaker.makeComputingMap 예를 들어 (기능)이있다).

이 설명을 목적으로 순진 구현 실제 구현은 많은 최적화를 포함한다.

내가 사용하는 옵션

은 여기에 있습니다 : https://bitbucket.org/atlassian/fugue/src/master/src/main/java/com/atlassian/fugue/Option.java

관련 문제