프로세스 = 실행 중인 애플리케이션
데이터, 컴퓨터 자원, 그리고 스레드로 구성
스레드 = 하나의 코드 실행 흐름
데이터와 애플리케이션이 확보한 자원을 활용하여 소스 코드를 실행한다.
자바 애플리케이션 실행 시 가장 먼저 실행되는 main메서드를 실행시켜주는 스레드
멀티 스레드 프로세스 =여러 개의 스레드를 가진 프로세스
멀티 스레딩 = 여러 스레드가 동시에 작업을 수행하는 것
스레드가 처리할 작업은 클래스 내부, run()
메서드 내부에 작성해야 한다.
run()
메서드작업 스레드를 생성, 실행 방법
public class Main {
public static void main(String[] args) {
// Runnable 인터페이스를 구현한 객체 생성
Runnable task1 = new ThreadTask1();
// Runnable 구현 객체를 인자로 전달하면서 Thread 클래스를 인스턴스화하여 스레드를 생성
Thread thread1 = new Thread(task1);
// 위의 두 줄을 아래와 같이 한 줄로 축약할 수도 있다.
// Thread thread1 = new Thread(new ThreadTask1());
// 작업 스레드를 실행시켜, run() 내부의 코드를 처리한다.
thread1.start();
// 반복문 추가
for (int i = 0; i < 100; i++) {
System.out.print("M");
if(i%25==0) {
System.out.println("");
}
}
}
}
class ThreadTask1 implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("J");
if(i%25==0) {
System.out.println("");
}
}
}
}
// 출력
M
MMMMMMMMMMMJ
JJJJJJJJJJMMMMMMMMMMMMMM
MJJJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJJJJMMMMMMMMMMMMMMMMMMMMMMJJJJJJJ
JJJJJJJJJJJJJJJMM
MMMMMMMMMMMMMJJJJMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMJJJJJJ
JJJJJJJJJJJJJJJJJJJJJJJJ
출력에서
M = 메인 스레드의 반복문에서 출력
J = 작업 스레드의 반복문에서 출력한 것이다.
메인 스레드와 작업 스레드가 동시에 병렬로 실행되어 두 문자가 섞인 것을 확인할 수 있었다.
(cf. 매 실행마다 출력값이 다를 수 있다.)
ublic class ThreadExample2 {
public static void main(String[] args) {
ThreadTask2 thread2 = new ThreadTask2();
// 작업 스레드를 실행시켜, run() 내부의 코드를 처리하도록 합니다.
thread2.start();
// 반복문 추가
for (int i = 0; i < 100; i++) {
System.out.print("@");
}
}
}
class ThreadTask2 extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("#");
}
}
}
public class ThreadExample1 {
public static void main(String[] args) {
// 익명 Runnable 구현 객체를 활용하여 스레드 생성
Thread thread1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("#");
}
}
});
thread1.start();
for (int i = 0; i < 100; i++) {
System.out.print("@");
}
}
}
public class ThreadExample2 {
public static void main(String[] args) {
// 익명 Thread 하위 객체를 활용한 스레드 생성
Thread thread2 = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.print("#");
}
}
};
thread2.start();
for (int i = 0; i < 100; i++) {
System.out.print("@");
}
}
}
메인스레드(이름: main)를 제외하고 추가적으로 생성한 스레드는 기본적으로 “Thread-n”이라는 이름을 가진다.
스레드의_참조값.getName()
로 스레드 이름 조회 가능
스레드의_참조값.setName()
로 스레드 이름 설정 가능
Thread.currentThread()
로 스레드 인스턴스의 주소값 사용하기 가능
public class Main {
public static void main(String[] args) {
//스레드 생성
Thread thread1 = new Thread(new Runnable() {
public void run() {
System.out.println("thread1의 이름 = " + Thread.currentThread().getName());
}
});
thread1.start();
//이름 조회
System.out.println("thread1.getName() = " + thread1.getName());
//이름 설정
thread1.setName("Thread name is wish");
//바꾼 이름 조회
System.out.println("thread1의 바뀐 이름 = " + thread1.getName());
//스레드 인스턴스의 주소값을 통해 스레드이름 조회
System.out.println(Thread.currentThread().getName());
}
}
//출력
thread1.getName() = Thread-0
thread1의 이름 = Thread-0
thread1의 바뀐 이름 = Thread name is wish
main
두개 이상의 스레드가 동일한 데이터를 공유하게 되어 문제가 발생할 수 있다.
(cf. 이때 발생하는 문제는 어떤 원인으로 어떤 오류가 날지 추측하기 어렵다.)
이러한 문제가 발생하지 않게 하는 것이 스레드 동기화다.
JVM = 자바로 작성한 소스 코드를 해석해 실행하는 별도의 프로그램
코드작성
-> 실행
-> 컴파일( .java 확장자 소스코드 -> .class 확장자 바이트 코드 파일로 변환)
-> JVM(운영 체제로 부터 메모리[Rumtime Data Area]
할당받음)
-> JVM(클래스 로더[Class Loader]
가 바이트 코드 파일을 런타임 데이터 영역에 적재시킴)
-> 실행 엔진(Execution Engine)이 런타임 데이터 영역에 적재된 바이트 코드를 실행
나머지는 자료출처에서 보자.
프로그램에서 더 이상 사용하지 않는 객체를 찾아 삭제하거나 제거하여 메모리를 확보하는 것