Java java지도 시간 Java에서 동기화를 사용하는 방법

Java에서 동기화를 사용하는 방법

Dec 13, 2016 am 11:04 AM
synchronized

synchronized는 Java의 키워드이며 일종의 동기화 잠금입니다. 수정하는 개체는 다음과 같습니다.
1. 코드 블록을 수정합니다. 수정된 코드 블록은 중괄호 {}로 묶인 코드입니다. 코드 블록의 객체;
2. 메소드 수정. 수정된 메소드를 동기화 메소드라고 하며, 해당 메소드가 작동하는 객체는
3. 정적 메서드 수정, 해당 작업 범위는 전체 정적 메서드이고 대상은 이 클래스의 모든 개체입니다.
4. 클래스 수정, 해당 작업 범위는 동기화 후 괄호로 묶인 부분입니다. 주요 개체는 이 클래스의 모든 개체입니다.

코드 블록 수정

스레드가 객체의 동기화된(this) 동기화 코드 블록에 액세스하면 해당 객체에 액세스하려는 다른 스레드가 차단됩니다. 다음 예를 살펴보겠습니다.

[Demo1]: 동기화 사용

/**
 * 同步线程
 */class SyncThread implements Runnable {   private static int count;   public SyncThread() {
      count = 0;
   }   public  void run() {      synchronized(this) {         for (int i = 0; i < 5; i++) {            try {
               System.out.println(Thread.currentThread().getName() + ":" + (count++));
               Thread.sleep(100);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
         }
      }
   }   public int getCount() {      return count;
   }
}
로그인 후 복사

SyncThread 호출:

SyncThread syncThread = new SyncThread();
Thread thread1 = new Thread(syncThread, "SyncThread1");
Thread thread2 = new Thread(syncThread, "SyncThread2");
thread1.start();
thread2.start();
로그인 후 복사

결과는 다음과 같습니다.

SyncThread1:0 
SyncThread1:1 
SyncThread1:2 
SyncThread1:3 
SyncThread1:4 
SyncThread2:5 
SyncThread2:6 
SyncThread2:7 
SyncThread2:8 
SyncThread2:9*
로그인 후 복사

두 개의 동시 스레드(thread1 및 thread2)가 동일한 객체(syncThread)의 동기화된 코드 블록에 액세스하면 동시에 하나의 스레드만 실행될 수 있으며 다른 스레드는 차단되어 대기해야 합니다. 현재 스레드는 실행을 완료합니다. 이 코드 블록은 나중에 실행될 수 있습니다. Thread1과 thread2는 동기화된 코드 블록이 실행될 때 현재 개체가 잠겨 있기 때문에 상호 배타적입니다. 개체 잠금은 코드 블록이 실행된 후에만 해제될 수 있으며 다음 스레드가 개체를 실행하고 잠글 수 있습니다.
SyncThread에 대한 호출을 살짝 변경해 보겠습니다.

Thread thread1 = new Thread(new SyncThread(), "SyncThread1");
Thread thread2 = new Thread(new SyncThread(), "SyncThread2");
thread1.start();
thread2.start();
로그인 후 복사

결과는 다음과 같습니다.

SyncThread1:0 
SyncThread2:1 
SyncThread1:2 
SyncThread2:3 
SyncThread1:4 
SyncThread2:5 
SyncThread2:6 
SyncThread1:7 
SyncThread1:8 
SyncThread2:9
로그인 후 복사

한 스레드가 동기화된 코드 블록을 실행하면, 다른 스레드가 차단되었나요? 위 예에서 thread1과 thread2가 동시에 실행되는 이유는 무엇입니까? 동기화는 객체만 잠그고, 각 객체에는 그에 연관된 잠금(lock)이 하나만 있기 때문이며, 위의 코드는 다음 코드와 동일합니다.

SyncThread syncThread1 = new SyncThread();
SyncThread syncThread2 = new SyncThread();
Thread thread1 = new Thread(syncThread1, "SyncThread1");
Thread thread2 = new Thread(syncThread2, "SyncThread2");
thread1.start();
thread2.start();
로그인 후 복사
로그인 후 복사

이때 SyncThread가 2개 생성됩니다. 개체 syncThread1 및 syncThread2, 스레드 thread1은 syncThread1 개체에서 동기화된 코드(실행)를 실행하고 스레드 thread2는 syncThread2 개체에서 동기화된 코드(실행)를 실행합니다. 우리는 동기화된 개체가 개체를 잠그고 두 개의 잠금 잠금이 있음을 알고 있습니다. syncThread1 객체와 syncThread2 객체는 각각 있으며, 이 두 잠금은 서로 간섭하지 않고 상호 배제를 형성하지 않으므로 두 스레드가 동시에 실행될 수 있습니다.

2. 스레드가 객체의 동기화된(this) 동기화 코드 블록에 액세스하면 다른 스레드는 여전히 객체의 동기화되지 않은(this) 동기화 코드 블록에 액세스할 수 있습니다.
[Demo2]: 다중 스레드가 동기화 및 비동기화 코드 블록에 액세스

class Counter implements Runnable{
   private int count;   public Counter() {      count = 0;
   }   public void countAdd() {
      synchronized(this) {         for (int i = 0; i < 5; i ++) {            try {
               System.out.println(Thread.currentThread().getName() + ":" + (count++));
               Thread.sleep(100);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
         }
      }
   }   //非synchronized代码块,未对count进行读写操作,所以可以不用synchronized
   public void printCount() {      for (int i = 0; i < 5; i ++) {         try {
            System.out.println(Thread.currentThread().getName() + " count:" + count);
            Thread.sleep(100);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }   public void run() {
      String threadName = Thread.currentThread().getName();      if (threadName.equals("A")) {
         countAdd();
      } else if (threadName.equals("B")) {
         printCount();
      }
   }
}
로그인 후 복사

호출 코드:

Counter counter = new Counter();
Thread thread1 = new Thread(counter, "A");
Thread thread2 = new Thread(counter, "B");
thread1.start();
thread2.start();
로그인 후 복사

결과는 다음과 같습니다.

A:0 
B count:1 
A:1 
B count:2 
A:2 
B count:3 
A:3 
B count:4 
A:4 
B count:5
로그인 후 복사

위 코드에서 countAdd는 동기화되고 printCount는 비동기화됩니다. 위의 결과를 보면, 스레드가 객체의 동기화된 코드 블록에 접근하면 다른 스레드가 블록되지 않고 객체의 비동기화 코드 블록에 접근할 수 있음을 알 수 있습니다.

개체를 잠그도록 지정

[Demo3]: 개체를 잠그도록 지정

/**
 * 银行账户类
 */class Account {
   String name;   float amount;   public Account(String name, float amount) {      this.name = name;      this.amount = amount;
   }   //存钱
   public  void deposit(float amt) {
      amount += amt;      try {
         Thread.sleep(100);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
   }   //取钱
   public  void withdraw(float amt) {
      amount -= amt;      try {
         Thread.sleep(100);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
   }   public float getBalance() {      return amount;
   }
}/**
 * 账户操作类
 */class AccountOperator implements Runnable{   private Account account;   public AccountOperator(Account account) {      this.account = account;
   }   public void run() {      synchronized (account) {
         account.deposit(500);
         account.withdraw(500);
         System.out.println(Thread.currentThread().getName() + ":" + account.getBalance());
      }
   }
}
로그인 후 복사

호출 코드:

Account account = new Account("zhang san", 10000.0f);
AccountOperator accountOperator = new AccountOperator(account);final int THREAD_NUM = 5;
Thread threads[] = new Thread[THREAD_NUM];for (int i = 0; i < THREAD_NUM; i ++) {
   threads[i] = new Thread(accountOperator, "Thread" + i);
   threads[i].start();
}
로그인 후 복사

결과는 다음과 같습니다.

Thread3:10000.0 
Thread2:10000.0 
Thread1:10000.0 
Thread4:10000.0 
Thread0:10000.0
로그인 후 복사

AccountOperator 클래스의 run 메소드에서는 동기화를 사용하여 계정 개체를 잠급니다. 이때, 스레드가 계정 개체에 접근하면 해당 스레드가 계정 개체에 접근할 때까지 해당 계정 개체에 접근하려는 다른 스레드는 차단됩니다. 즉, 잠금을 얻은 사람은 누구나 잠금이 제어하는 ​​코드를 실행할 수 있습니다.
잠금으로 명확한 개체가 있는 경우 다음과 유사한 방식으로 프로그램을 작성할 수 있습니다.

public void method3(SomeObject obj)
{   //obj 锁定的对象
   synchronized(obj)
   {      // todo
   }
}
로그인 후 복사

잠금 역할을 하는 명시적인 개체가 없고 코드 일부만 동기화하려는 경우 잠금 역할을 할 특수 개체를 만들 수 있습니다.

class Test implements Runnable{
   private byte[] lock = new byte[0];  // 特殊的instance变量
   public void method()
   {
      synchronized(lock) {         // todo 同步代码块
      }
   }   public void run() {

   }
}
로그인 후 복사

설명: 길이가 0인 바이트 배열 객체는 어떤 객체보다 생성하는 것이 더 경제적입니다. 컴파일된 바이트코드를 살펴보세요. 길이가 0인 byte[] 객체를 생성하려면 3개의 opcode만 필요한 반면, Object lock = new Object()에는 7줄의 코드가 필요합니다. opcode.

메서드 수정

동기화 메소드 수정은 매우 간단합니다. 즉, 메소드 앞에 동기화를 추가하고, public syncified void method(){//todo}를 추가하면 동기화됩니다. 코드 블록을 수정합니다. 비슷하지만 범위가 다릅니다. 수정된 코드 블록은 중괄호로 묶인 범위이고, 수정된 메서드의 범위는 전체 함수입니다. [Demo1]의 실행 방법을 다음 방법으로 변경해도 효과는 동일합니다.

*[Demo4]: 동기화는 메소드를 수정합니다.

public synchronized void run() {   for (int i = 0; i < 5; i ++) {      try {
         System.out.println(Thread.currentThread().getName() + ":" + (count++));
         Thread.sleep(100);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
   }
}
로그인 후 복사

Synchronized는 전체 메소드에 대해 작동합니다.
작성 방법 1:

public synchronized void method()
{
   // todo
}
로그인 후 복사

작성 방법 2:

public void method(){
   synchronized(this) {
      // todo
   }}
로그인 후 복사

작성 방법 1은 방법을 수정하고, 방법 2를 작성하면 코드 블록을 수정하지만, 방법 1을 작성하고 작성 두 번째 방법은 동일하며 전체 방법이 잠겼을 때의 내용입니다.

在用synchronized修饰方法时要注意以下几点:
1. synchronized关键字不能继承。
虽然可以使用synchronized来定义方法,但synchronized并不属于方法定义的一部分,因此,synchronized关键字不能被继承。如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上synchronized关键字才可以。当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。这两种方式的例子代码如下:
在子类方法中加上synchronized关键字

class Parent {
   public synchronized void method() { }
}class Child extends Parent {
   public synchronized void method() { }
}
로그인 후 복사

在子类方法中调用父类的同步方法

class Parent {
   public synchronized void method() {   }
}class Child extends Parent {
   public void method() { super.method();   }
}
로그인 후 복사

在定义接口方法时不能使用synchronized关键字。

构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步。

修饰一个静态的方法

Synchronized也可修饰一个静态方法,用法如下:

public synchronized static void method() {
   // todo
}
로그인 후 복사

我们知道静态方法是属于类的而不属于对象的。同样的,synchronized修饰的静态方法锁定的是这个类的所有对象。我们对Demo1进行一些修改如下:

【Demo5】:synchronized修饰静态方法

/**
 * 同步线程
 */class SyncThread implements Runnable {   private static int count;   public SyncThread() {
      count = 0;
   }   public synchronized static void method() {      for (int i = 0; i < 5; i ++) {         try {
            System.out.println(Thread.currentThread().getName() + ":" + (count++));
            Thread.sleep(100);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }   public synchronized void run() {
      method();
   }
}
로그인 후 복사

调用代码:

SyncThread syncThread1 = new SyncThread();
SyncThread syncThread2 = new SyncThread();
Thread thread1 = new Thread(syncThread1, "SyncThread1");
Thread thread2 = new Thread(syncThread2, "SyncThread2");
thread1.start();
thread2.start();
로그인 후 복사
로그인 후 복사

结果如下:

SyncThread1:0 
SyncThread1:1 
SyncThread1:2 
SyncThread1:3 
SyncThread1:4 
SyncThread2:5 
SyncThread2:6 
SyncThread2:7 
SyncThread2:8 
SyncThread2:9
로그인 후 복사

syncThread1和syncThread2是SyncThread的两个对象,但在thread1和thread2并发执行时却保持了线程同步。这是因为run中调用了静态方法method,而静态方法是属于类的,所以syncThread1和syncThread2相当于用了同一把锁。这与Demo1是不同的。

修饰一个类

Synchronized还可作用于一个类,用法如下:

class ClassName {
   public void method() {
      synchronized(ClassName.class) {
         // todo
      }
   }
}
로그인 후 복사

我们把Demo5再作一些修改。
【Demo6】:修饰一个类

/**
 * 同步线程
 */
class SyncThread implements Runnable {
   private static int count;

   public SyncThread() {
      count = 0;
   }

   public static void method() {
      synchronized(SyncThread.class) {
         for (int i = 0; i < 5; i ++) {
            try {
               System.out.println(Thread.currentThread().getName() + ":" + (count++));
               Thread.sleep(100);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
         }
      }
   }

   public synchronized void run() {
      method();
   }
}
로그인 후 복사

其效果和【Demo5】是一样的,synchronized作用于一个类T时,是给这个类T加锁,T的所有对象用的是同一把锁。

总结:

A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。 
B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。 
C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Java의 동기화 원리 및 사용 시나리오와 Callable 인터페이스의 사용 및 차이점 분석 Java의 동기화 원리 및 사용 시나리오와 Callable 인터페이스의 사용 및 차이점 분석 Apr 21, 2023 am 08:04 AM

1. 기본 기능 1. 낙관적 잠금으로 시작하여 잠금 충돌이 빈번하면 비관적 잠금으로 변환됩니다. 2. 경량 잠금 구현으로 시작하여 잠금이 오랫동안 유지되면 잠금이 해제됩니다. 3. 경량 잠금을 구현할 때 가장 많이 사용되는 스핀 잠금 전략 4. 불공정 잠금 5. 재진입 잠금 6. 읽기-쓰기 잠금이 아님 2. JVM 잠금 프로세스를 동기화합니다. 잠금은 잠금 없음, 편향된 잠금, 경량 잠금 및 중량 잠금 상태로 구분됩니다. 상황에 따라 순차적으로 업그레이드될 예정입니다. 편향된 자물쇠는 남자 주인공이 자물쇠이고 여자 주인공이 실이라고 가정합니다. 이 스레드만 이 자물쇠를 사용하면 남자 주인공과 여자 주인공은 결혼 증명서를 받지 못해도 영원히 행복하게 살 수 있습니다. -비용 운영) 그러나 여성 조연이 나타납니다.

Java 키워드 동기화 원리 및 잠금 상태 예시 분석 Java 키워드 동기화 원리 및 잠금 상태 예시 분석 May 11, 2023 pm 03:25 PM

1. Java의 잠금 개념 스핀 잠금: 스레드가 잠금을 획득할 때 다른 스레드가 잠금을 획득한 경우 스레드는 루프에서 대기한 후 다음까지 잠금을 성공적으로 획득할 수 있는지 계속 판단합니다. 잠금이 획득되면 루프가 종료됩니다. 낙관적 잠금: 충돌이 없다고 가정하고 데이터 수정 시 이전에 획득한 데이터와 일치하지 않는 데이터가 발견되면 최신 데이터를 읽고 수정을 다시 시도합니다. 비관적 잠금: 동시성 충돌이 발생할 것이라고 가정하고 데이터와 관련된 모든 작업을 동기화하며 데이터를 읽는 시점부터 잠금을 시작합니다. 배타적 잠금(쓰기): 리소스에 쓰기 잠금을 추가합니다. 스레드는 리소스를 수정할 수 있지만 다른 스레드는 리소스를 다시 잠글 수 없습니다(단일 쓰기). 공유 잠금(읽기): 리소스에 읽기 잠금을 추가한 후에는 읽을 수만 있고 수정할 수는 없습니다. 다른 스레드는 읽기 잠금만 추가할 수 있고 쓰기 잠금(다중)은 추가할 수 없습니다. S로 본다

Java에서 동기화 메커니즘을 구현하기 위해 동기화를 사용하는 방법은 무엇입니까? Java에서 동기화 메커니즘을 구현하기 위해 동기화를 사용하는 방법은 무엇입니까? Apr 22, 2023 pm 02:46 PM

Java 1에서 동기화를 사용하는 방법 요약입니다. 함수 수정자로 동기화를 사용하는 경우 샘플 코드는 다음과 같습니다. Publicsynchronizedvoidmethod(){//….} 이것이 동기화 방법입니다. 그러면 이때 어떤 개체가 동기화됩니까? 그가 잠그는 것은 이 동기화된 메소드 객체를 호출하는 것입니다. 즉, 객체 P1이 서로 다른 스레드에서 이 동기화 방법을 실행하면 이들 사이에 상호 배제가 형성되어 동기화 효과를 얻을 수 있습니다. 그러나 이 객체가 속한 Class에 의해 생성된 또 다른 객체 P2는 동기화 키워드를 추가하여 이 메소드를 임의로 호출할 수 있습니다. 위의 샘플 코드 등

Java의 세 가지 동기화 방법은 무엇이며 어떻게 사용합니까? Java의 세 가지 동기화 방법은 무엇이며 어떻게 사용합니까? Apr 27, 2023 am 09:34 AM

1. 동기화는 가장 일반적으로 사용되는 동기화 방법이며 이를 사용하는 세 가지 주요 방법이 있음을 설명합니다. 2. 예시//일반 클래스 메서드 동기화synchronousdpublidvoidinvoke(){}//클래스 정적 메서드 동기화 동기화publicstaticvoidinvoke(){}//코드 블록 동기화 동기화(객체){}이 세 가지 메서드의 차이점은 동기화되는 개체가 다르다는 것입니다. 일반 클래스는 객체 자체를 동기화하고, 정적 메서드는 클래스 자체를 동기화하며, 코드 블록은 대괄호 안에 채워진 객체를 동기화합니다. Java에는 어떤 컬렉션이 있나요?

Java 동기화 잠금 업그레이드의 원칙과 프로세스는 무엇입니까? Java 동기화 잠금 업그레이드의 원칙과 프로세스는 무엇입니까? Apr 19, 2023 pm 10:22 PM

도구 준비 동기화의 원리에 대해 공식적으로 이야기하기 전에 스핀 잠금에 대해 먼저 이야기하겠습니다. 스핀 잠금은 동기화 최적화에 큰 역할을 하기 때문입니다. 스핀락을 이해하려면 먼저 원자성이 무엇인지 이해해야 합니다. 소위 원자성은 단순히 각 작업이 완료되지 않았거나 완료되었음을 의미합니다. 예를 들어, 변수 데이터에 하나를 추가하려면 다음 세 단계가 있습니다. 데이터 추가 로드 메모리에서 레지스터로. 데이터 값에 1을 더합니다. 결과를 다시 메모리에 씁니다. 원자성은 스레드가 증분 작업을 수행할 때 이 스레드가 이 세 가지 프로세스를 완료할 때만 다른 스레드에 의해 중단될 수 없음을 의미합니다.

Java가 단순히 동기화된 키워드를 사용하는 대신 잠금을 제공해야 하는 이유는 무엇입니까? Java가 단순히 동기화된 키워드를 사용하는 대신 잠금을 제공해야 하는 이유는 무엇입니까? Apr 20, 2023 pm 05:01 PM

요약: 동기화된 키워드는 하나의 스레드만 동기화된 코드 블록에 액세스할 수 있도록 Java에서 제공됩니다. syncised 키워드가 제공되는데 Java SDK 패키지에 Lock 인터페이스도 제공되는 이유는 무엇입니까? 이것이 불필요한 바퀴의 재발명인가요? 오늘 우리는 이 문제에 대해 함께 논의해 보겠습니다. 동기화된 키워드는 하나의 스레드만 동기화된 코드 블록에 액세스할 수 있도록 Java에서 제공됩니다. syncised 키워드가 제공되는데 Java SDK 패키지에 Lock 인터페이스도 제공되는 이유는 무엇입니까? 이것이 불필요한 바퀴의 재발명인가요? 오늘은 함께 토론해보자

Java 동기화란 무엇입니까? Java 동기화란 무엇입니까? May 14, 2023 am 08:28 AM

동기화란 무엇입니까? Java 독자는 여러 미들웨어 소스 코드나 JDK 소스 코드에서 볼 수 있습니다. -스레딩 동기화는 스레드 안전성을 보장할 수 있습니다. 이를 뮤텍스 잠금(동시에 하나의 스레드만 실행할 수 있고 다른 스레드는 대기함)이라고 하며 비관적 잠금(동시에 하나의 스레드만 실행할 수 있으며 다른 스레드는 대기함)이라고도 합니다. 이를 구현하는 데 도움이 되도록 개발자는 동기화된 키워드만 사용하면 됩니다. 이를 사용할 때 객체를 잠금용 뮤텍스로 사용해야 합니다.

Java에는 몇 개의 비액세스 수정자가 있습니까? Java에는 몇 개의 비액세스 수정자가 있습니까? Aug 30, 2023 pm 06:01 PM

Java는 가시성 이상의 기능을 제공하기 위해 몇 가지 다른 수정자를 제공합니다. 이러한 수정자를 비액세스 수정자라고 합니다. static으로 선언된 정적 멤버는 클래스의 모든 인스턴스에 공통됩니다. 정적 멤버는 클래스 메모리에 저장되는 클래스 수준 멤버입니다. Final 이 수정자는 변수, 메서드 또는 클래스에 대한 추가 수정을 제한하는 데 사용됩니다. final로 선언된 변수의 값은 일단 값을 얻은 후에는 수정할 수 없습니다. Final 메서드는 하위 클래스에서 재정의될 수 없으며 Final 클래스의 하위 클래스를 만들 수도 없습니다. Abstract 이 수정자는 클래스 또는 메서드와 함께 사용할 수 있습니다. 변수와 생성자에는 이 수정자를 적용할 수 없습니다. abstract로 선언된 메서드는 서브클래스에서 수정되어야 합니다. abstract로 선언된 클래스를 인스턴스화할 수 없습니다. 동기 이 수정자는 여러 스레드를 제어하는 ​​데 사용됩니다.

See all articles