[java] Java에서 동기화 된 정적 메소드는 어떻게 작동하며 Hibernate 엔티티를로드하는 데 사용할 수 있습니까?

기본 데이터 액세스를 달성하기 위해 Hibernate 함수를 호출하는 정적 메소드가있는 util 클래스가있는 경우. synchronized스레드 안전성을 보장하기 위해 방법을 만드는 것이 올바른 방법인지 궁금합니다 .

동일한 DB 인스턴스에 대한 정보 액세스를 막기 위해 이것을 원합니다. 그러나 getObjectById특정 클래스에서 호출 할 때 다음 코드가 모든 클래스에 대해 호출 되지 않는지 확신합니다 .

public class Utils {
     public static synchronized Object getObjectById (Class objclass, Long id) {
           // call hibernate class
         Session session = new Configuration().configure().buildSessionFactory().openSession();
         Object obj = session.load(objclass, id);
         session.close();
         return obj;
     }

     // other static methods
}



답변

정적 메소드 잠금에서 동기화를 사용하면 클래스 메소드 및 속성을 동기화합니다 (인스턴스 메소드 및 속성과 반대)

따라서 당신의 가정은 맞습니다.

메소드를 동기화시키는 것이 스레드 안전성을 보장하는 올바른 방법인지 궁금합니다.

실제로는 아닙니다. 대신 RDBMS가 해당 작업을 수행하도록해야합니다. 그들은 이런 종류의 것들을 잘합니다.

데이터베이스에 대한 액세스를 동기화하여 얻을 수있는 유일한 것은 응용 프로그램을 매우 느리게 만드는 것입니다. 또한 게시 한 코드에서 매번 세션 팩토리를 작성하면 응용 프로그램이 실제 작업을 수행하는 것보다 DB에 액세스하는 데 더 많은 시간을 소비합니다.

다음 시나리오를 상상해보십시오.

클라이언트 A와 B는 테이블 T의 레코드 X에 다른 정보를 삽입하려고합니다.

접근 방식을 사용하면 DB에서 어쨌든 발생할 때 RDBMS가 A의 절반 정보와 B의 절반 정보를 동시에 삽입하지 못하게되므로 하나만 호출해야합니다. . 결과는 같지만 5 배 이상 느립니다.

아마도 최대 절전 모드 설명서 의 “트랜잭션 및 동시성” 장을 살펴 보는 것이 좋습니다 . 대부분의 경우 해결하려는 문제는 이미 해결되었으며 훨씬 더 나은 방법입니다.


답변

더 일반적으로 질문을 해결하기 위해 …

동기화 된 메소드를 사용하는 것은 실제로는 속기입니다 (클래스가 SomeClass라고 가정).

synchronized static void foo() {
    ...
}

와 같다

static void foo() {
    synchronized(SomeClass.class) {
        ...
    }
}

synchronized void foo() {
    ...
}

와 같다

void foo() {
    synchronized(this) {
        ...
    }
}

모든 객체를 잠금으로 사용할 수 있습니다. 정적 메소드의 서브 세트를 잠 그려면 다음을 수행하십시오.

class SomeClass {
    private static final Object LOCK_1 = new Object() {};
    private static final Object LOCK_2 = new Object() {};
    static void foo() {
        synchronized(LOCK_1) {...}
    }
    static void fee() {
        synchronized(LOCK_1) {...}
    }
    static void fie() {
        synchronized(LOCK_2) {...}
    }
    static void fo() {
        synchronized(LOCK_2) {...}
    }
}

(정적이 아닌 메소드의 경우 잠금을 정적이 아닌 필드로 만들고 싶습니다)


답변

정적 메서드는 클래스를 잠금의 개체로 사용합니다 (예제에서는 Utils.class). 예, 괜찮습니다.


답변

static synchronized클래스의 Class객체 를 잠그는 것을 의미 합니다.
synchronized 그 클래스의 객체 자체에 잠금을 보유하는 수단. 즉, 실행중인 스레드에서 비 정적 동기화 방법에 액세스하는 경우 다른 스레드를 사용하여 정적 동기화 방법에 계속 액세스 할 수 있습니다.

따라서 스레드보다 많은 시점에서 두 가지 동일한 종류의 메소드 (두 정적 또는 두 개의 비 정적 메소드)에 액세스하는 것은 불가능합니다.


답변

단일 스레드 만 한 번에 DB에 액세스 할 수 있도록하는 이유는 무엇입니까?

데이터베이스 드라이버의 작업은 필요한 잠금을 가정하여 필요한 잠금을 구현하는 것입니다.Connection 가 한 번에 하나의 스레드에서만 사용 !

데이터베이스는 여러 개의 병렬 액세스를 완벽하게 처리 할 수 ​​있습니다.


답변

데이터베이스의 데이터와 관련이 있다면 데이터베이스 격리 잠금을 사용하여 달성하지 않겠습니까?


답변

귀하의 질문에 대답하기 위해 그렇습니다 synchronized. 한 번에 두 개 이상의 스레드에서 메소드를 실행할 수 없습니다.