Programing

Erlang 프로세스 대 Java 스레드

lottogame 2020. 12. 11. 07:42
반응형

Erlang 프로세스 대 Java 스레드


저는 Saša Jurić의 "Elixir in Action"책을 읽고 있는데, 첫 번째 장에서 다음과 같이 말합니다.

Erlang 프로세스는 서로 완전히 격리되어 있습니다. 그들은 메모리를 공유하지 않으며 한 프로세스의 충돌이 다른 프로세스의 충돌을 일으키지 않습니다.

Java 스레드에서도 마찬가지입니까? 즉, Java 스레드가 충돌 할 때 다른 스레드도 충돌하지 않습니다. 특히 요청 처리 스레드를보고있는 경우 ( main이 토론 에서 스레드를 제외 할 수 있습니다 )


나를 따라 반복 : "이것들은 다른 패러다임"

20 번 정도 큰 소리로 말하십시오.

우리가 정말로 사과와 오렌지를 비교해야 한다면 적어도 "과일이되는 것"의 공통적 인 측면이 교차하는 부분을 고려해 봅시다.

Java "객체"는 Java 프로그래머의 기본 계산 단위입니다. 즉, 객체 (기본적으로 C ++보다 약간 더 엄격하게 캡슐화되는 팔과 다리가있는 구조체 )는 세계를 모델링하는 기본 도구입니다. 당신은 "이 객체는 그것을 알고 / 갖고 Data {X,Y,Z}수행 Functions {A(),B(),C()}하며, Data그것이가는 모든 곳을 운반하고 , 공용 인터페이스의 일부로 정의 된 함수 / 메소드를 호출하여 다른 객체와 통신 할 수 있습니다. 그것은 명사이고 명사 는 그렇게합니다. 즉, 이러한 계산 단위를 중심으로 사고 프로세스를 지향합니다. 기본 사례는 객체 사이에서 발생하는 일이 순서대로 발생하고 충돌이 해당 순서를 방해하는 것입니다. 따라서 "객체"라고합니다. (Alan Kay의 원래 의미를 무시하면) "객체 방향"을 얻습니다.

Erlang "프로세스"는 Erlang 프로그래머의 기본 계산 단위입니다. 과정은 (기본적으로 시간과 공간 그 자체에서 실행되는 자체 포함 연속 프로그램) 기본 도구 인주의 얼이 모델 세계 (1). Java 객체가 캡슐화 수준을 정의하는 방법과 유사하게 Erlang 프로세스는 캡슐화 수준도 정의하지만 Erlang의 경우 계산 단위는 완전히서로 차단합니다. 다른 프로세스에서 메서드 나 함수를 호출 할 수 없으며 그 안에있는 데이터에 액세스 할 수 없으며 한 프로세스가 다른 프로세스와 동일한 타이밍 컨텍스트 내에서 실행되지도 않으며 메시지 수신 상대의 순서에 대한 보장도 없습니다. 메시지를 보낼 수있는 다른 프로세스에. 그들은 완전히 다른 행성에있을 수도 있습니다 (그리고 생각해 보면 실제로 그럴듯합니다). 그들은 서로 독립적으로 충돌 할 수 있으며 다른 프로세스는 고의적으로 영향을 받도록 선택한 경우에만 영향을받습니다. 시스템 전체에 상대적인 질서, 반응을 선택할 수도 있고 선택하지 않을 수도 있습니다).

Java는 복합 알고리즘에서 직접 복잡성을 처리합니다. 즉, 문제를 해결하기 위해 개체가 함께 작동하는 방식입니다. 단일 실행 컨텍스트 내에서이를 수행하도록 설계되었으며 Java의 기본 경우는 순차 실행입니다. Java의 다중 스레드는 다중 실행 컨텍스트를 나타내며 서로 다른 타이밍 컨텍스트의 영향 활동이 서로 (그리고 시스템 전체 : 따라서 방어 프로그래밍, 예외 체계 등)에 영향을 미치기 때문에 매우 복잡한 주제입니다. 자바에서 "다중 스레드"라는 말 Erlang에서하는 것과는 다른 것입니다. 사실 이것은 항상 기본 케이스이기 때문에 Erlang에서는 결코 말하지 않습니다. 여기서 Java 스레드는 메모리 나 가시적 참조가 아닌 시간과 관련된 분리를 의미합니다. Java의 가시성은 개인과 공용을 선택하여 수동으로 제어됩니다. 시스템의 보편적으로 액세스 할 수있는 요소는 "스레드 세이프"및 재진입이 가능하도록 설계되거나 대기열 메커니즘을 통해 순차적으로 지정되거나 잠금 메커니즘을 채택해야합니다. 요컨대 : 스케줄링은 스레드 / 동시 Java 프로그램에서 수동으로 관리되는 문제입니다.

Erlang은 실행 타이밍 (스케줄링), 메모리 액세스 및 참조 가시성 측면에서 각 프로세스의 실행 컨텍스트를 분리하고이를 통해 알고리즘의 각 구성 요소를 완전히 분리하여 단순화합니다.. 이것은 기본적인 경우가 아니라이 계산 모델에서 사용할 수있는 유일한 경우입니다. 이는 처리 시퀀스의 일부가 메시지 장벽을 통과하면 주어진 작업의 시퀀스를 정확히 알지 못하는 대가로 발생합니다. 왜냐하면 메시지는 기본적으로 모두 네트워크 프로토콜이고 주어진 내에서 실행되도록 보장 할 수있는 메서드 호출이 없기 때문입니다. 문맥. 이것은 객체별로 JVM 인스턴스를 생성하고 소켓을 통해서만 통신 할 수 있도록 허용하는 것과 유사합니다. Java에서는 엄청나게 번거롭지 만 Erlang이 작동하도록 설계된 방식입니다 (부수적으로 이것은 개념의 기본이기도합니다. 웹 지향적 인 짐을 버리면 "자바 마이크로 서비스"를 작성하는 것에는 유행어가 수반하는 경향이 있습니다. Erlang 프로그램은 기본적으로 마이크로 서비스 무리입니다. 트레이드 오프에 관한 모든 것.

이것들은 다른 패러다임입니다. 우리가 찾을 수있는 가장 가까운 공통점은 프로그래머의 관점에서 볼 때 Erlang 프로세스가 Java 객체와 유사하다는 것입니다. 자바 쓰레드를 비교할 무언가를 찾아야한다면 ... 글쎄, 우리는 Erlang에서 그런 것을 찾지 못할 것입니다. 왜냐하면 Erlang에는 그러한 유사한 개념이 없기 때문입니다. 죽은 말을 이기기 위해 : 이것들은 다른 패러다임 입니다. Erlang으로 사소하지 않은 몇 가지 프로그램을 작성하면 쉽게 알 수 있습니다.

"이것들은 서로 다른 패러다임"이라고 말하고 있지만 OOP 대 FP의 주제는 다루지 않았습니다. "Java로 생각하기"와 "Erlang으로 생각하기"의 차이는 OOP 대 FP보다 더 근본적입니다.

Erlang의 "동시성 지향"또는 "프로세스 지향"기반이 Alan Kay가 "객체 지향"(2)이라는 용어를 만들 때 염두에 두었던 것에 더 가깝다는 것은 사실이지만, 여기서는 그게 사실이 아닙니다. Kay가 얻은 것은 컴퓨터를 별개의 청크로 절단하여 시스템의인지 복잡성을 줄일 수 있다는 것이며,이를 위해서는 격리가 필요합니다. Java는 기본적으로는 본질적으로 절차 적이지만 "클래스 정의"라고하는 고차 디스패치 클로저에 대한 특수 구문을 중심으로 코드를 구성하는 방식으로이를 수행합니다. Erlang은 실행중인 컨텍스트를 개체별로 분할하여이를 수행합니다. 즉, Erlang 사물은 서로 메서드를 호출 할 수 없지만 Java 사물은 할 수 있습니다. 즉, Erlang 사물은 분리되어 충돌 할 수 있지만 Java 사물은 충돌 할 수 없습니다. 이 기본적인 차이에서 엄청난 수의 함의가 흘러 나옵니다. 따라서 "다른 패러다임"이됩니다. 트레이드 오프.


각주 :

  1. 덧붙여서, Erlang은 " 배우 모델 " 의 버전을 구현 하지만, Erlang이이 모델의 대중화보다 앞서 기 때문에이 용어를 사용하지 않습니다. Joe는 Erlang을 디자인 하고 논문을 썼을 때 그것을 인식하지 못했습니다 .
  2. 앨런 케이 (Alan Kay)는 말했다에 대한 꽤 그가 용어를 만들어 낸 때 자신이 무엇을 의미하는지 , "객체 지향"되는 가장 흥미로운 그의 포획을 (다른 자신의 타이밍과 메모리를 하나 개의 독립적 인 과정에서 편도 알림) VS 통화 메시징에을 ( 공유 메모리가있는 순차 실행 컨텍스트 내에서 함수 또는 메서드 호출)-프로그래밍 언어와 그 아래의 구현에서 제공하는 프로그래밍 인터페이스 사이에 선이 어떻게 흐려지는 지.

확실히 아닙니다. Java의 모든 스레드는 동일한 주소 공간을 공유하므로 한 스레드가 다른 스레드가 소유 한 것을 폐기 할 수 있습니다. Erlang VM에서는 각 프로세스가 다른 모든 프로세스와 분리되어 있기 때문에 가능하지 않습니다. 그게 전부입니다. 한 프로세스가 다른 프로세스의 데이터로 작업을 수행하도록하려면 코드가 다른 프로세스에 메시지를 보내야합니다. 프로세스간에 공유되는 유일한 것은 큰 이진 객체이며 변경 불가능합니다.


Java 프로세스는 실제로 메모리를 공유 할 수 있습니다. 예를 들어 동일한 인스턴스를 두 개의 개별 스레드로 전달할 수 있고 둘 다 상태를 조작하여 교착 상태 와 같은 잠재적 인 문제를 일으킬 수 있습니다 .

반면에 Elixir / Erlang은 불변성의 개념으로이를 해결하므로 프로세스에 무언가를 전달할 때 원래 값의 복사본이됩니다.


Java 스레드가 죽으면 다른 스레드에도 영향을주지 않습니다.

반대 질문을하겠습니다. 왜 Thread.stop()10 년 이상 사용이 중단되었다고 생각 하십니까? 그 이유는 정확히 위의 진술을 부정하기 때문입니다.

두 가지 구체적인 예를 들자면 : stop()처럼 무해하게 들리는 무언가를 실행하는 동안 스레드가 있습니다. 결과 :이 두 기능은 이제 전체 JVM에서 손상되었습니다. 응용 프로그램에서 실행할 수있는 다른 동기화 코드에도 동일하게 적용됩니다.System.out.println()Math.random()

요청 처리 스레드를보고 있다면

이론적으로 애플리케이션 잠금으로 보호되는 공유 자원이 전혀 사용되지 않도록 코딩 될 수 있습니다. 그러나 이는 Java 스레드가 상호 의존하는 정확한 범위를 지적하는 데만 도움이됩니다. 그리고 달성 된 "독립성"은 그러한 애플리케이션의 모든 스레드가 아닌 요청 처리 스레드에만 관련됩니다 .


이전 답변을 보완하기 위해 Java 스레드에는 데몬과 비 데몬의 두 가지 유형이 있습니다.

스레드 유형을 변경하려면 .setDaemon(boolean on). 차이점은 데몬 스레드가 JVM이 종료되는 것을 방지하지 않는다는 것입니다. Thread 용 Javadoc에 따르면 다음과 같습니다.

Java Virtual Machine은 실행중인 스레드가 모두 데몬 스레드 인 경우 종료됩니다.

That means: user threads (those that are not specifically set to be daemon) keeps the JVM from terminating. On the other hand, daemon threads MAY BE RUNNING when all non-daemon threads are finished in which case the JVM will quit. So, to answer your question: you can start a thread that does not quit the JVM when it finishes.

As to the comparison with Erlang/Elixir don't forget: they are different paradigms, as already mentioned.

It is not impossible for the JVM to mimic Erlang's behaviour though it is not for what it was intended to and, therefore, it goes with lots of trade-offs. The following projects tries to accomplish that:


Isn't that true for Java threads as well? I mean when Java thread crashes, it too does not crash other threads

Yes and No. I explain:

  • Referring to shared memory: Different threads in a Java process share the whole heap, therefore threads can interact in a huge number of planned and unplanned ways. However objects in the stack (e.g. a context you pass down to called method) or a ThreadLocal are their own thread's (unless they start sharing references).

  • Crashing: If a thread crashes in Java (a Throwable is propagated into Thread.run(), or something gets looped or blocked), that mishap might not affect other threads (e.g. a pool of connections in a server will continue to operate). However as different threads interact. Other threads will easily get stranded if one of them ends abnormally (e.g. one thread trying to read from an empty pipe from another thread which did not close its end). So unless the developers are highly paranoid careful, it is very likely that side effects will occur.

I doubt that any other paradigm intends threads to operate as totally independent islands. They must share information and coordinate somehow. And then there will be the chance to mess things up. It is just they will take a more defensive approach that "gives you less rope to hang yourself" (same idiom as with pointers).

참고URL : https://stackoverflow.com/questions/32294367/erlang-processes-vs-java-threads

반응형