JavaRush /Java Blog /Random-KO /커피 브레이크 #165. Java의 패키지. 초보자를 위한 스레드로부터 안전한 방법

커피 브레이크 #165. Java의 패키지. 초보자를 위한 스레드로부터 안전한 방법

Random-KO 그룹에 게시되었습니다

자바 패키지

출처: Usemynotes 이 게시물은 Java 패키지를 더 잘 이해하고 패키지의 목적과 구현 방법을 이해하는 데 도움이 될 것입니다. 커피 브레이크 #165.  Java의 패키지.  초보자를 위한 스레드로부터 안전한 방법 - 1

Java의 패키지 란 무엇입니까?

Java의 패키지는 클래스, 인터페이스 및 하위 패키지 그룹을 함께 그룹화하는 방법입니다. 패키지는 관련 클래스, 인터페이스, 열거형 등의 그룹을 만드는 데 사용됩니다. 하위 패키지 는 다른 패키지 내에 있는 패키지입니다. 기본적으로 가져오지 않지만 필요한 경우 수동으로 가져올 수 있습니다. 액세스 사양은 하위 패키지의 개별 구성원에게 제공되지 않으며 별도의 패키지로 처리됩니다.

Java의 일부 패키지 유형:

  • java.lang - 기본적으로 Java와 함께 번들로 제공됩니다.
  • java.io - 입력/출력과 관련된 클래스, 메소드 및 기타 요소를 포함합니다.

패키지가 필요한 이유는 무엇입니까?

  • 이름 충돌을 피하기 위해.
  • 통제된 접근을 제공하기 위해.
  • 데이터 캡슐화를 달성합니다.

Java로 패키지를 만드는 방법은 무엇입니까?

컴퓨터 라는 패키지를 만들어 보겠습니다 . 일반적으로 패키지 이름은 소문자로 작성됩니다. 이는 클래스 이름과의 이름 충돌을 피하기 위해서만 수행됩니다. 또한 컴퓨터 패키지 에 위치할 Pluggable 이라는 인터페이스도 만들 것입니다 .
package computer;

interface Pluggable {
   public void pluggedIn();
   public void pluggedOut();
}
이제 위의 인터페이스를 구현할 PenDrive 라는 클래스를 만듭니다 .
package computer;

public class PenDrive implements Pluggable {

   int storage = 64;

   public void pluggedIn () {
     System.out.println("Pen Drive is connected");
   }

   public void pluggedOut () {
     System.out.println("Pen Drive is removed");
   }

   public int storage() {
     return storage;
   }

   public static void main(String args[]) {
     PenDrive p = new PenDrive ();
     p.pluggedIn();
     System.out.println("Pen Drive Storage: " + p.storage());
     p.pluggedOut();
   }
}

Java에서 패키지 계층 구조를 만드는 방법은 무엇입니까?

계층 구조를 형성할 때 Java 패키지 이름은 역순으로 지정됩니다. 이는 디렉터리나 폴더와 매우 유사합니다. 하나의 폴더에 하나 이상의 하위 폴더가 포함될 수 있는 개인용 컴퓨터와 마찬가지로 Java 패키지에도 동일하게 적용됩니다. Asia.India.Kolkata 라는 패키지를 살펴보겠습니다 . 이것들은 모두 기존 폴더이지만 지리를 고려하면 캘커타는 인도에 있고 인도는 아시아에 있음이 분명합니다. 계층 구조의 주요 목적은 클래스를 더 쉽게 찾을 수 있도록 하는 것입니다.

Java의 패키지 유형

내장 패키지

내장 패키지는 Java API의 일부인 다수의 내장 클래스로 구성된 패키지입니다. 이러한 패키지에는 다음이 포함됩니다.
  • java.util - 이 패키지에는 연결된 목록, 집합 등과 같은 데이터 구조를 구현하는 데 사용되는 한정된 수의 유틸리티 클래스가 포함되어 있습니다. 또한 날짜 및 시간 작업 등을 지원합니다.
  • java.net - 네트워크 작업에 사용되는 클래스가 포함되어 있습니다.

사용자 정의 패키지

사용자가 정의한 패키지를 사용자 패키지라고 합니다. 사용자는 패키지를 수동으로 생성하고 원하는 만큼 많은 클래스를 포함할 수 있습니다.

다른 패키지에서 패키지에 액세스하는 방법은 무엇입니까?

세 가지 간단한 방법으로 다른 패키지에서 패키지에 액세스할 수 있습니다.
  • import 문에서 별표 사용
별표( * ) 문자는 Java에서 "모든 것"을 나타내는 데 사용됩니다. 이를 사용하면 패키지의 하위 패키지 안에 있는 모든 것을 가져올 수 있습니다. 예: tools 라는 패키지를 고려해보세요 . 이 패키지 안에 있는 모든 것을 가져오려면 다음과 같은 import 문을 사용해야 합니다.
import tools.*;
  • import package.ClassName 사용 ;
패키지에서 클래스 이름을 언급하는 것은 필요한 클래스만 프로그램으로 가져오는 효과적인 방법이므로 불필요한 클래스를 가져오는 것을 방지할 수 있습니다. 예: books 라는 패키지를 생각해 보세요 . 특정 클래스나 인터페이스만 가져오려는 경우( Pages 클래스 를 살펴보겠습니다 ) 다음을 사용하여 해당 클래스나 인터페이스만 가져올 수 있습니다.
import book.Pages;
  • 귀하의 성명을 사용하여
정규화된 이름을 사용하여 Java 패키지 또는 해당 클래스를 직접 사용하는 방법이 있습니다. 이렇게 하면 패키지를 가져올 필요 없이 프로그램에서 직접 사용할 수 있습니다. 예:
java.awt.List aSimpleList = new java.awt.List();

Java의 기본 배치 크기

기본적으로 Java는 java.lang 패키지를 가져옵니다 . String , Integer 등과 같은 간단한 Java 프로그램에서 일반적으로 사용되는 많은 클래스가 있습니다 . 가장 중요한 클래스 중 하나는 Object 클래스이며, 이는 java.lang 패키지 에도 있습니다 . 이 패키지의 크기는 해당 구성 요소(인터페이스 8개, 클래스 37개, 열거형 3개, 예외 27개, 오류 유형 23개, 주석 유형 5개)를 기반으로 합니다.

초보자를 위한 스레드로부터 안전한 Java 방법

출처: Medium 이 기사를 사용하면 Java에서 스레드 안전 메서드의 작동에 대해 배울 수 있습니다. 커피 브레이크 #165.  Java의 패키지.  초보자를 위한 스레드로부터 안전한 방법 - 2나는 많은 주니어/중간 Java 개발자들이 스레드로부터 안전한 메소드가 실제 프로젝트에서 어떻게 작동해야 하는지 오해하고 있다는 것을 발견했습니다. 그리고 우리는 일반적으로 다중 스레드 환경에서 작업하므로 올바른 사용이 매우 중요합니다. 스레드로부터 안전한 메서드는 서로의 데이터 상태에 영향을 주지 않고 여러 스레드에서 동시에 호출할 수 있는 메서드입니다. 이 개념에 대한 이해가 부족하면 발견하고 수정하기 어려운 버그가 발생합니다. 이러한 실수를 방지하기 위해 예를 살펴보겠습니다.

예시 #1:

public static int countLetters(String input) {
    int counter = 0;

    for (Character c : input.toCharArray()) {
        if (Character.isAlphabetic(c)) {
            counter++;
        }
    }

    return counter;
}
  • countLetters 메소드 는 정적이며 int 값을 반환 하고 문자열 매개변수를 입력으로 받습니다.
  • 기본 변수 카운터가 메서드 내부에 생성된 다음 루프는 입력 문자열의 문자를 반복하고 문자가 나타날 때마다 변수 카운터를 증가시킵니다.
이 메소드 스레드는 안전한가요? 많은 개발자들은 아니오라고 말합니다. 왜냐하면 이 경우에는 스레드로부터 안전하지 않은 증분 작업이 있기 때문입니다. 그것을 알아 봅시다. Java 메모리 모델에는 스택과 힙이 있습니다. 각 스레드에는 자체 스택이 있으며 모든 스레드는 동일한 힙을 공유합니다. 이와 관련하여 스택 데이터는 항상 스레드로부터 안전하지만 힙 데이터는 그렇지 않습니다. 스택은 기본 요소와 개체 참조를 저장합니다. 힙에는 개체 자체가 포함됩니다. 이는 이 코드 예제에서 각 스레드가 자신의 변수 카운터를 스택에 저장하고 다른 스레드의 데이터에 아무런 영향을 미치지 않으므로 메서드가 스레드로부터 안전 하다는 것을 의미합니다 . 입력 String 값 도 객체이지만 String 및 기본 래퍼( Integer , Long , Double , Boolean 등)는 변경할 수 없기 때문에 스레드로부터 안전합니다.

예시 #2:

public static int countLetters2(String input) {
    List<Character> listCounter = new ArrayList<>();

    for (Character c : input.toCharArray()) {
        if (Character.isAlphabetic(c)) {
            listCounter.add(c);
        }
    }

    return listCounter.size();
}
이 코드는 첫 번째 예제와 동일한 논리를 사용했지만 기본 int 변수 대신 List 객체를 사용했습니다 . 이전 부분에서 우리는 Java의 객체가 힙에 저장되고 List 가 객체라는 것을 알았습니다. 또한 스택이 힙의 개체에 대한 참조를 저장한다는 것도 알고 있습니다. 예제 #2에서 각 스레드는 새로운 ArrayList 객체를 생성 하고 listCounter 변수는 해당 객체에 대한 참조를 힙에 저장하므로 다른 스레드는 해당 객체를 변경할 수 없습니다.
List<Character> listCounter = new ArrayList<>();
이는 이 메서드가 스레드로부터 안전하다는 것을 의미합니다.

예시 #3:

public class CounterUtil { // singleton

    List<Character> listCounter = new ArrayList<>();

    public int countLetters3(String input) {
        for (Character c : input.toCharArray()) {
            if (Character.isAlphabetic(c)) {
                listCounter.add(c);
            }
        }

        return listCounter.size();
    }
}
이 예에는 전역 변수 listCounter 가 있는 싱글톤(중요) 클래스 CounterUtil이 있습니다 . 이 변수는 싱글톤 인스턴스와 동시에 생성됩니다. 여러 스레드가 countChars3 메서드를 호출하면 모두 동일한 전역 변수 listCounter를 사용합니다 . 이 변수는 힙에 동일한 객체에 대한 참조를 저장하며 거기에 있는 스레드는 서로 영향을 미칩니다. 따라서 이 방법은 스레드로부터 안전하지 않다고 결론을 내릴 수 있습니다. 그리고 List<Character> listCounter를 기본 변수 int counter 로 변경하더라도 모든 스레드가 동일한 기본 변수를 사용하기 때문에 스레드로부터 안전하지 않습니다.

마지막 예:

public static int countLetters4(List<Character> inputList) {
    List<Character> listCounter = new ArrayList<>();

    for (Character c : inputList) {
        if (Character.isAlphabetic(c)) {
            listCounter.add(c);
        }
    }

    return listCounter.size();
}
countLetters4 메소드는 String 매개 변수 대신 문자 목록을 허용합니다 . 여기서는 이 메서드가 스레드로부터 안전하다고 보장할 수 없습니다 . 왜? 개발자가 이 방법을 어떻게 사용할지 확신할 수 없기 때문입니다. 외부의 다른 스레드가 counterLetters4 메소드 와 동시에 inputList 의 데이터를 변경하는 경우 최종 결과에 영향을 미칠 수 있습니다.

결론

우리는 네 가지 예만 살펴보았는데 Java 프로젝트의 스레드 안전성에 대한 모든 측면을 다루지는 않지만 시작하기에 좋은 곳입니다. 다음에 코드에서 메소드를 볼 때 "이 메소드가 스레드로부터 안전한가?"라고 자문해 보십시오. 그리고 곧 당신은 대답을 명확하게 이해하게 될 것입니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION