클래스를 한 수행하거나 WAS를 기동하면 서버에 자바 프로세스가 생성이 됩니다.
하나의 프로세스에는 여러개의 스레드가 생성이됩니다. 단일 스레드가 생성되어 종료될 수도 있고 여러 개의 스레드가 생성되어 수행될 수도 있습니다.
스레드
- Thread 클래스를 상송 받는 방법과 Runnable 인터페이스를 구현하는 방법 두 가지가 있습니다. 기본적으로 Thread클래스는 Runnable 인터페이스를 구현한 것이기 때문에 어느 것을 사용해도 차이가 없지만 Runnable 인터페이스를 구현하면 원하는 기능을 추가할 수 있습니다. 그러나 이 방법을 사용하기 위해서는 해당 클래스 사용시 별도의 스레드 객체를 생성해야 하는 점이 있습니다. 또한 자바는 다중 상속을 지원하지 않으므로 이미 상속받은 클래스가 존재하면 Runnable 인터페이스를 구현해야 합니다.
- Thread 클래스 상속한 경우 에는 start()메서드를 호출하여 수행하겨 Runnable인터페이스를 구현한 경우 Runnable 인터페이스를 매개변수로 받는 생성자를 이용해 Thread 클래스 생성 후 start()를 호출해야 합니다.
- 여러 스레드가 있을 때 우선순위가 정해지지 않은 경우 무작위로 호출이 됩니다.
sleep(), wait(), join()
- 현재 스레드를 대기하도록 할 수 있습니다.
- wait()의 경우 Object클래스에 선언되어 있으므로 어떤 클래스에서도 사용이 가능합니다.
- 이 메서드들은 예외를 던지므로 반드시 예외처리를 해주어야 합니다.
- sleep() 메서드는 명시된 시간만큼 해당 스레드를 대기 시킵니다.
- wait() 메서드는 명시된 시간만큼 해당 스레드를 대기 시키는데 sleep()과 다른점은 매개변수를 지정하지 않을 경우 notify()나 notifyAll() 메서드가 호출될 때까지 대기합니다.
- join()메서드는 명시된 시간만큼 해당 스레드가 죽기를 기다립니다. 매개변수를 지정하지 않았을 경우 죽을때 까지 대기합니다.
interrupt(), notify(), notifyAll()
- sleep(), wait(), join() 모두를 멈출 수 있는 메서드는 interrupt() 메서드입니다.
- interrupt() 메서드가 호출되면 중지된 스레드에는 익셉션이 발생하게 됩니다.
- 제대로 수행되었는지 확인을 위해 interrupted() 혹은 isInterrupted()를 호출하면 되는데 두방법의 차이는 interrupted()는 상태를 변경시키지만 isInterrupted()메서드는 단지 상태만을 리턴합니다.
- notify()메서드와 notifyAll() 메서드 모두 wait() 메서드가 호출된 후 대기 상태로 바뀐 스레드를 깨웁니다. notify()는 단일 스레드를 깨우며 notifyAll() 메서드는 모든 스레드를 깨우게 됩니다.
interrupt()메서드는 모든 상황에서 동작하는 것이 아니라 특정상황이나 대기 상황에서 동작되어집니다.
while(true)의 경우 무한루프에 들어가고 interrupt() 사용하면서 멈추게 하는 방법은 flag를 사용하여 while 매개변수에 true의 flag 값을 주고 interrupt 시 flag의 값을 false로 변경해주는 것입니다. 혹은 sleep()을 이용해 대기상태로 만들어 interrupt()를 호출하여 멈추는 방법입니다.
=> 해당 상황은 대기 상태일 때 interrupt가 적용되는 것을 보여주기 위한 것이였습니다.
sychronized
- sychronized는 하나의 객체에 여러 객체가 동시에 접근할 때 발생됩니다.
- 메서드와 블록으로 사용할 수 있습니다.
- 생성자와 식별자에는 사용할 수 없습니다.
- 하나의 객체를 여러 스레드에서 동시에 사용하거나 static으로 선언한 객체를 여러 스레드에서 동시에 사용할 경우 사용합니다.
- 하나의 객체에 여러 스레드에서 동시에 사용하게 되면 원하는 결과 값이 나오지 않을 수 있으므로 sleep()으로 대기시간을 주고 sychronized를 통해 한번에 하나의 스레드만 접근할 수 있게 만들어 주어야 합니다.
- 동기화의 경우 성능에 영향을 주므로 반드시 필요한 부분에서만 동기화를 사용해야 합니다.
- sychronized는 각각의 객체에 대한 동기화를 하는것이기 때문에 static의 필드를 사용하더라도 동기화 되지 않습니다. 이때 static sychronized로 메서드를 변경해주면 원하는 결과 값이 나옵니다. 하지만 항상 변하는 값에 대해서 static을 사용할 경우는 위험하고 sychronized도 반드시 필요할 경우에만 사용해야합니다.
JDK5.0부터 concurrent패키지가 추가되었습니다.
- Lock : 실행 중인 스레드를 간단한 방법으로 정지 시켰다가 실행시키는데 상호참조로 인해 발생하는 데드락을 피할 수 있습니다.
- Executors: 스레드를 더 효율적으로 관리할 수 있는 클래스를 제공하며 스레드 풀 또한 제공하고 있습니다.
- Concurrent컬렉션 : 컬렉션의 클래스들을 제공합니다.
- Atomic 변수 : 동기화가 되어있는 변수를 제공하며 해당 변수를 사용하면 synchronized를 메서드에 지정할 필요없이 사용이가능합니다.
'학습(구) > Java(구)' 카테고리의 다른 글
| 자바 성능 튜닝 - 로그 (0) | 2021.06.07 |
|---|---|
| 자바 성능 튜닝 - I/O에서 발생하는 병목 현상 (0) | 2021.06.07 |
| 자바 성능 튜닝 - reflection (0) | 2021.06.05 |
| 자바 성능 튜닝 - static (0) | 2021.06.04 |
| 자바 성능 튜닝 - 조건/반복문 (0) | 2021.06.04 |