자바 멀티스레드: 개념과 활용 방법

자바 멀티스레드는 CPU를 최대한 활용하기 위해 두 개 이상의 스레드를 동시에 실행하는 과정을 의미합니다. 자바에서의 스레드는 적은 리소스를 필요로 하며 프로세스 리소스를 생성하고 공유하는 데 사용됩니다.

멀티스레딩과 멀티프로세싱

멀티스레딩과 멀티프로세싱은 자바에서 멀티태스킹을 위해 사용되지만, 우리는 멀티스레딩을 멀티프로세싱보다 선호합니다. 이는 스레드가 메모리를 공유하는 데 도움이 되며 또한 스레드 간의 컨텍스트 전환은 프로세스보다 빠르기 때문입니다.

멀티스레딩의 장점

멀티스레딩의 몇 가지 장점은 다음과 같습니다:

  • 여러 작업을 동시에 수행하여 시간을 절약할 수 있습니다.
  • 스레드는 독립적이기 때문에 사용자가 동시에 여러 작업을 수행하는 데 차단되지 않으며, 하나의 스레드에서 예외가 발생해도 다른 스레드에 영향을 미치지 않습니다.

스레드의 생명 주기

스레드는 다섯 가지 상태를 거쳐야 합니다. 이 생명 주기는 JVM(Java Virtual Machine)에 의해 제어됩니다. 이러한 상태는 다음과 같습니다:

  1. 새로 생성된 스레드는 ‘New’ 상태로 시작됩니다. 이는 태어난 스레드라고도 합니다. 스레드는 Thread 클래스의 인스턴스를 생성하되 start() 메서드를 호출하기 전에 ‘New’ 상태에 있습니다.
  2. ‘Runnable’ 상태는 새로 생성된 스레드가 시작된 후에 발생합니다. 이 상태에서 스레드는 작업을 실행할 수 있습니다.
  3. ‘Running’ 상태는 스레드 스케줄러가 스레드를 선택한 경우에 발생합니다.
  4. ‘Non-Runnable (Blocked)’ 상태는 스레드가 여전히 활성 상태이지만 현재 실행될 수 없는 상태를 말합니다.
  5. ‘Terminated’ 상태는 다음과 같은 이유로 스레드가 종료된 경우입니다:
  • run() 메서드가 정상적으로 종료되어 스레드의 코드가 프로그램을 실행한 경우
  • 세그먼트 오류(segmentation fault)나 처리되지 않은 예외(unhandled exception)와 같은 예외로 인해 종료된 경우 종료된 스레드는 CPU의 사이클을 소비하지 않습니다.

자바 스레드 클래스

자바 스레드 클래스는 스레드를 생성하고 작업을 수행하기 위한 메서드와 생성자를 제공합니다. 자바 스레드 클래스는 Object 클래스를 확장하고 Runnable 인터페이스를 구현합니다.

자바 스레드 메서드

자바에서는 Thread 클래스에 다양한 메서드들이 제공되고 있는데, 이 중 몇 가지 주요한 메서드들을 살펴보도록 하겠습니다. 이 메서드들은 각각의 역할과 기능을 가지고 있으며, 스레드의 실행과 관리를 위해 사용됩니다.

1. public void start()

start() 메서드는 스레드의 실행을 시작하고, 해당 스레드 객체에서 run()을 호출합니다. 이를 통해 스레드의 실행이 시작됩니다.

예시:

public class StartExp1 extends Thread {
    public void run() {
        System.out.println("Thread is running...");
    }

    public static void main(String args[]) {
        StartExp1 thread1 = new StartExp1();
        thread1.start();
    }
}

출력:

Thread is running...

2. public void run()

run() 메서드는 스레드에서 수행할 작업을 정의합니다. 이 메서드는 별도의 Runnable 객체를 사용하여 스레드가 생성된 경우에 호출됩니다.

예시:

public class RunExp1 implements Runnable {
    public void run() {
        System.out.println("Thread is running...");
    }

    public static void main(String args[]) {
        RunExp1 r1 = new RunExp1();
        Thread thread1 = new Thread(r1);
        thread1.start();
    }
}

출력:

Thread is running...

3. public static void sleep()

sleep() 메서드는 현재 실행 중인 스레드를 지정된 시간만큼 대기 상태로 만듭니다.

예시:

public class SleepExp1 extends Thread {
    public void run() {
        for (int i = 1; i < 5; i++) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
            System.out.println(i);
        }
    }

    public static void main(String args[]) {
        SleepExp1 thread1 = new SleepExp1();
        SleepExp1 thread2 = new SleepExp1();
        thread1.start();
        thread2.start();
    }
}

출력:

1
1
2
2
3
3
4
4

4. public static Thread currentThread()

currentThread() 메서드는 현재 실행 중인 스레드에 대한 참조를 반환합니다.

예시:

public class CurrentThreadExp extends Thread {
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }

    public static void main(String args[]) {
        CurrentThreadExp thread1 = new CurrentThreadExp();
        CurrentThreadExp thread2 = new CurrentThreadExp();
        thread1.start();
        thread2.start();
    }
}

출력:

Thread-0
Thread-1

5. public void join()

join() 메서드는 현재 스레드를 다른 스레드가 종료될 때까지 기다리도록 합니다. 또는 특정 시간(밀리초)만큼 기다릴 수도 있습니다.

예시:

public class JoinExample1 extends Thread {
    public void run() {
        for (int i = 1; i <= 4; i++) {
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                System.out.println(e);
            }
            System.out.println(i);
        }
    }

    public static void main(String args[]) {
        JoinExample1 thread1 = new JoinExample1();
        JoinExample1 thread2 = new JoinExample1();
        JoinExample1 thread3 = new JoinExample1();
        thread1.start();
        try {
            thread1.join();
        } catch (Exception e) {
            System.out.println(e);
        }
        thread2.start();
        thread3.start();
    }
}

출력:

1
2
3
4
1
1
2
2
3
3
4
4

6. public final int getPriority()

getPriority() 메서드는 스레드의 우선 순위를 확인할 수 있습니다. 스레드가 생성될 때 우선 순위가 부여되며, 기본적으로는 1부터 10까지의 값을 가집니다.

예시:

public class JavaGetPriorityExp extends Thread {
    public void run() {
        System.out.println("running thread name is:" + Thread.currentThread().getName());
    }

    public static void main(String args[]) {
        JavaGetPriorityExp t1 = new JavaGetPriorityExp();
        JavaGetPriorityExp t2 = new JavaGetPriorityExp();
        System.out.println("t1 thread priority : " + t1.getPriority());
        System.out.println("t2 thread priority : " + t2.getPriority());
        t1.start();
        t2.start();
    }
}

출력:

t1 thread priority : 5
t2 thread priority : 5
running thread name is:Thread-0
running thread name is:Thread-1

7. public final void setPriority()

setPriority() 메서드는 스레드의 우선 순위를 변경하는 데 사용됩니다. 스레드의 우선 순위는 1부터 10까지의 범위로 표현되며, 높은 숫자일수록 높은 우선 순위를 가집니다.

예시:

public class JavaSetPriorityExp1 extends Thread {
    public void run() {
        System.out.println("Priority of thread is: " + Thread.currentThread().getPriority());
    }

    public static void main(String args[]) {
        JavaSetPriorityExp1 t1 = new JavaSetPriorityExp1();
        t1.setPriority(Thread.MAX_PRIORITY);
        t1.start();
    }
}

출력:

Priority of thread is: 10

8. public final String getName()

getName() 메서드는 스레드의 이름을 반환합니다. 이 메서드는 프로그램에서 오버라이드할 수 없는 final 메서드입니다.

예시:

public class GetNameExample extends Thread {
    public void run() {
        System.out.println("Thread is running...");
    }

    public static void main(String args[]) {
        GetNameExample thread1 = new GetNameExample();
        GetNameExample thread2 = new GetNameExample();
        System.out.println("Name of thread1: " + thread1.getName());
        System.out.println("Name of thread2: " + thread2.getName());
        thread1.start();
        thread2.start();
    }
}

출력:

Name of thread1: Thread-0
Name of thread2: Thread-1
Thread is running...
Thread is running...

9. public final void setName()

setName() 메서드는 스레드의 이름을 변경하는 데 사용됩니다.

예시:

public class SetNameExample extends Thread {
    public void run() {
        System.out.println("running...");
    }

    public static void main(String args[]) {
        SetNameExample thread1 = new SetNameExample();
        SetNameExample thread2 = new SetNameExample();
        thread1.start();
        thread2.start();
        thread1.setName("Kadamb Sachdeva");
        thread2.setName("Great Learning");
        System.out.println("After changing name of thread1: " + thread1.getName());
        System.out.println("After changing name of thread2: " + thread2.getName());
    }
}

출력:

After changing name of thread1: Kadamb Sachdeva
After changing name of thread2: Great Learning
running...
running...

10. public long getId()

getId() 메서드는 스레드의 식별자를 반환합니다. 이 식별자는 스레드가 생성될 때 할당되며, 스레드의 생애주기 동안 변경되지 않습니다.

예시:

public class GetIdExample extends Thread {
    public void run() {
        System.out.println("running...");
    }

    public static void main(String args[]) {
        GetIdExample thread1 = new GetIdExample();
        System.out.println("Name of thread1: " + thread1.getName());
        System.out.println("Id of thread1: " + thread1.getId());
        thread1.start();
    }
}

출력:

Name of thread1: Thread-0
Id of thread1: 21
running...

11. public final boolean isAlive()

isAlive() 메소드는 스레드가 활성화되어 있는지를 확인합니다. 스레드는 start() 메소드가 호출되고 스레드가 종료되지 않았을 때 활성화 상태에 있습니다.

예시:

public class JavaIsAliveExp extends Thread {
    public void run() {
        try {
            Thread.sleep(300);
            System.out.println("is run() method isAlive " + Thread.currentThread().isAlive());
        } catch (InterruptedException ie) {
        }
    }

    public static void main(String[] args) {
        JavaIsAliveExp thread1 = new JavaIsAliveExp();
        System.out.println("before starting thread isAlive: " + thread1.isAlive());
        thread1.start();
        System.out.println("after starting thread isAlive: " + thread1.isAlive());
    }
}

결과:

before starting thread isAlive: false
after starting thread isAlive: true
is run() method isAlive true

12. public static void yield()

yield() 메소드는 현재 스레드의 실행을 일시적으로 멈추고 다른 스레드를 실행시킵니다.

예시:

public class JavaYieldExp extends Thread {
    public void run() {
        for (int i = 0; i < 3; i++)
            System.out.println(Thread.currentThread().getName() + " in control");
    }

    public static void main(String[] args) {
        JavaYieldExp thread1 = new JavaYieldExp();
        JavaYieldExp thread2 = new JavaYieldExp();
        thread1.start();
        thread2.start();
        for (int i = 0; i < 3; i++) {
            thread1.yield();
            System.out.println(Thread.currentThread().getName() + " in control");
        }
    }
}

결과:

main in control
main in control
main in control
Thread-0 in control
Thread-0 in control
Thread-0 in control
Thread-1 in control
Thread-1 in control
Thread-1 in control

13. public final void suspend()

suspend() 메소드는 현재 실행 중인 스레드를 일시적으로 중지시킵니다. resume() 메소드를 사용하여 중지된 스레드를 다시 시작할 수 있습니다.

예시:

public class JavaSuspendExp extends Thread {
    public void run() {
        for (int i = 1; i < 5; i++) {
            try {
                sleep(500);
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                System.out.println(e);
            }
            System.out.println(i);
        }
    }

    public static void main(String args[]) {
        JavaSuspendExp thread1 = new JavaSuspendExp();
        JavaSuspendExp thread2 = new JavaSuspendExp();
        JavaSuspendExp thread3 = new JavaSuspendExp();
        thread1.start();
        thread2.start();
        thread2.suspend();
        thread3.start();
    }
}

결과:

Thread-0
1
Thread-2
1
Thread-0
2
Thread-2
2
Thread-0
3
Thread-2
3
Thread-0
4
Thread-2
4

14. public final void resume()

resume() 메서드는 중단된 스레드를 다시 실행시키는 데 사용됩니다. 이 메서드는 suspend() 메서드와 함께 사용되며, 중단된 스레드를 다시 활성화시킬 때 사용됩니다.

예시:

public class JavaResumeExp extends Thread {    
    public void run() {    
        for(int i=1; i<5; i++) {    
            try {  
                sleep(500);  
                System.out.println(Thread.currentThread().getName());    
            } catch(InterruptedException e) {
                System.out.println(e);
            }    
            System.out.println(i);    
        }    
    }    

    public static void main(String args[]) {    
        JavaResumeExp thread1 = new JavaResumeExp ();    
        JavaResumeExp thread2 = new JavaResumeExp ();   
        JavaResumeExp thread3 = new JavaResumeExp ();   
        thread1.start();  
        thread2.start();  
        thread2.suspend();
        thread3.start();   
        thread2.resume();
    }    
}

이를 실행하면 스레드가 중단되고 다시 시작되는 예시를 확인할 수 있습니다.

15. public final void stop()

stop() 메서드는 현재 실행 중인 스레드를 중지시키는 데 사용됩니다. 스레드 실행이 중지된 후에는 다시 시작할 수 없다는 점을 기억해야 합니다.

예시:

public class JavaStopExp extends Thread {    
    public void run() {    
        for(int i=1; i<5; i++) {    
            try {  
                sleep(500);  
                System.out.println(Thread.currentThread().getName());    
            } catch(InterruptedException e) {
                System.out.println(e);
            }    
            System.out.println(i);    
        }    
    }    

    public static void main(String args[]) {    
        JavaStopExp thread1 = new JavaStopExp ();    
        JavaStopExp thread2 = new JavaStopExp ();   
        JavaStopExp thread3 = new JavaStopExp ();   
        thread1.start();  
        thread2.start();  
        thread3.stop();  
        System.out.println("Thread thread3 is stopped");    
    }    
}

위 예시에서는 스레드가 중지되고, 중지된 스레드는 다시 시작할 수 없음을 확인할 수 있습니다.

16. public void destroy()

destroy() 메서드는 스레드 그룹과 해당 하위 그룹을 모두 제거하는 역할을 합니다.

예시:

public class JavaDestroyExp extends Thread {  
    JavaDestroyExp(String threadname, ThreadGroup tg) {  
        super(tg, threadname);  
        start();  
    }  

    public void run() {  
        for (int i = 0; i < 2; i++) {  
            try {  
                Thread.sleep(10);  
            } catch (InterruptedException ex) {  
                System.out.println("Exception encounterted");
            }  
        }  
        System.out.println(Thread.currentThread().getName() + " finished executing");  
    }  

    public static void main(String arg[]) throws InterruptedException, SecurityException {  
        ThreadGroup g1 = new ThreadGroup("Parent thread"); 
        ThreadGroup g2 = new ThreadGroup(g1, "child thread");  
        JavaDestroyExp thread1 = new JavaDestroyExp("Thread-1", g1);  
        JavaDestroyExp thread2 = new JavaDestroyExp("Thread-2", g1);  
        thread1.join();  
        thread2.join();  
        g2.destroy();  
        System.out.println(g2.getName() + " destroyed");  
        g1.destroy();  
        System.out.println(g1.getName() + " destroyed");  
    }  
}

17. public final boolean isDaemon()

이 스레드 메서드는 스레드가 데몬 스레드인지 아닌지를 확인합니다. 만약 데몬 스레드라면 true를 반환하고, 그렇지 않다면 false를 반환합니다.

데몬 스레드에 대해 모르는 사람을 위해 설명하자면, 데몬 스레드란 프로그램이 종료될 때 JVM(Java Virtual Machine)을 멈추지 않지만 스레드는 여전히 실행 중인 스레드입니다.

예시:

public class JavaIsDaemonExp extends Thread  
{    
    public void run()  
    {    
        //데몬 스레드인지 확인    
        if(Thread.currentThread().isDaemon())  
        {  
            System.out.println("데몬 스레드 작업");    
        }    
        else 
        {    
            System.out.println("사용자 스레드 작업");    
        }    
    }    
    public static void main(String[] args)  
    {    
        JavaIsDaemonExp thread1=new JavaIsDaemonExp();   
        JavaIsDaemonExp thread2=new JavaIsDaemonExp();    
        JavaIsDaemonExp thread3=new JavaIsDaemonExp();    
        thread1.setDaemon(true);  
        thread1.start();   
        thread2.start();    
        thread3.start();    
    }    
}  

출력:

데몬 스레드 작업

사용자 스레드 작업

사용자 스레드 작업

18. public final void setDaemon(boolean on)

이 스레드 메서드는 스레드를 데몬 스레드 또는 사용자 스레드로 표시하거나 표시하는 데 사용됩니다. 모든 사용자 스레드가 종료되면 JVM이 이 스레드를 자동으로 종료합니다.

이 스레드 메서드는 스레드의 실행이 시작되기 전에 실행되어야 합니다.

예시:

public class JavaSetDaemonExp1 extends Thread  
{    
    public void run()  
    {    
        if(Thread.currentThread().isDaemon())  
        {  
            System.out.println("데몬 스레드 작업");    
        }    
        else 
        {    
            System.out.println("사용자 스레드 작업");    
        }    
    }    
    public static void main(String[] args)  
    {    
        JavaSetDaemonExp1 thread1=new JavaSetDaemonExp1();   
        JavaSetDaemonExp1 thread2=new JavaSetDaemonExp1();    
        JavaSetDaemonExp1 thread3=new JavaSetDaemonExp1();    
        thread1.setDaemon(true);  
        thread1.start();   
        thread2.setDaemon(true);  
        thread2.start();    
        thread3.start();    
    }    
}   

출력:

데몬 스레드 작업

데몬 스레드 작업

사용자 스레드 작업

19. public void interrupt()

이 스레드 메서드는 현재 실행 중인 스레드를 중단하는 데 사용됩니다. 이 메서드는 스레드가 sleep 상태이거나 waiting 상태일 때만 호출될 수 있습니다.

그러나 스레드가 sleep 상태나 waiting 상태가 아니라면 interrupt() 메서드는 스레드를 중단하지 않고 interrupt 플래그를 true로 설정합니다.

예시:

public class JavaInterruptExp1 extends Thread  
{    
    public void run()  
    {    
        try 
        {    
            Thread.sleep(1000);    
            System.out.println("javatpoint");    
        }catch(InterruptedException e){    
            throw new RuntimeException("스레드가 중단되었습니다..."+e);  

        }    
    }    
    public static void main(String args[])  
    {    
        JavaInterruptExp1 thread1=new JavaInterruptExp1();    
        thread1.start();    
        try 
        {    
            thread1.interrupt();    
        }catch(Exception e){System.out.println("예외 처리됨 "+e);}    
    }    
}    

출력:

스레드 내 예외 발생: "Thread-0" java.lang.RuntimeException: 스레드가 중단되었습니다...java.lang.InterruptedException: sleep interrupted at JavaInterruptExp1.run(JavaInterruptExp1.java:10)

20. public boolean isInterrupted()

이 스레드 메서드는 스레드가 중단되었는지 여부를 테스트하는 데 사용됩니다. 스레드가 중단되었다면 내부 플래그 값을 true 또는 false로 반환하며, 스레드가 중단되었다면 true를 반환하고 그렇지 않으면 false를 반환합니다.

예시:

public class JavaIsInterruptedExp extends Thread   
{   
    public void run()   
    {   
        for(int i=1;i<=3;i++)   
        {   
            System.out.println("작업 중....: "+i);   
        }   
    }   
    public static void main(String args[])throws InterruptedException   
    {   
        JavaIsInterruptedExp thread1=new JavaIsInterruptedExp();   
        JavaIsInterruptedExp thread2=new JavaIsInterruptedExp();   
        thread1.start();   
        thread2.start();  
        System.out.println("스레드가 중단되었는지..: "+thread1.isInterrupted());  
        System.out.println("스레드가 중단되었는지..: "+thread2.isInterrupted());  
        thread1.interrupt();   
        System.out.println("스레드가 중단되었는지..: " +thread1.isInterrupted());   
        System.out.println("스레드가 중단되었는지..: "+thread2.isInterrupted());   
    }  
}  

출력:

스레드가 중단되었는지..: false

스레드가 중단되었는지..: false

스레드가 중단되었는지..: true

스레드가 중단되었는지..: false

작업 중....: 1

작업 중....: 2

작업 중....: 3

작업 중....: 1

작업 중....: 2

작업 중....: 3

21. public static boolean interrupted()

이 메소드는 현재 쓰레드(Thread)가 중단되었는지 여부를 확인하는 데 사용된다. 이 메소드를 연속으로 두 번 호출하면 두 번째 호출은 false를 반환한다.

쓰레드의 인터럽트 상태가 true이면, 이 메소드는 이를 false로 설정한다.

예시:

public class JavaInterruptedExp extends Thread {   
    public void run() {   
        for(int i=1;i<=3;i++) {   
            System.out.println("작업 중....: "+i);   
        }   
    }   

    public static void main(String args[]) throws InterruptedException {   
        JavaInterruptedExp thread1 = new JavaInterruptedExp();   
        JavaInterruptedExp thread2 = new JavaInterruptedExp();   
        thread1.start();   
        thread2.start();  
        System.out.println("쓰레드 thread1은 중단되었는가..:"+thread1.interrupted()); 
        thread1.interrupt();   
        System.out.println("쓰레드 thread1은 중단되었는가..:"+thread1.interrupted());   
        System.out.println("쓰레드 thread2은 중단되었는가..:"+thread2.interrupted());   
    }  
}

출력:

쓰레드 thread1은 중단되었는가..: false
쓰레드 thread1은 중단되었는가..: false
쓰레드 thread2은 중단되었는가..: false
작업 중....: 1
작업 중....: 2
작업 중....: 3
작업 중....: 1
작업 중....: 2
작업 중....: 3

22. public static int activeCount()

이 메소드는 현재 실행 중인 쓰레드(thread) 그룹 내의 활성 쓰레드 수를 반환하는 데 사용된다.

이 메소드가 반환하는 숫자는 내부 데이터 구조를 탐색하는 동안 쓰레드 수가 동적으로 변경되기 때문에 추정치일 뿐이다.

예시:

public class JavaActiveCountExp extends Thread {  
    JavaActiveCountExp(String threadname, ThreadGroup tg) {  
        super(tg, threadname);  
        start();  
    }  
    public void run() {  
       System.out.println("실행 중인 쓰레드 이름: "
+Thread.currentThread().getName());    
    }  
    public static void main(String arg[]) {  
        ThreadGroup g1 = new ThreadGroup("부모 쓰레드 그룹");  
        JavaActiveCountExp thread1 = new JavaActiveCountExp("Thread-1", g1);  
        JavaActiveCountExp thread2 = new JavaActiveCountExp("Thread-2", g1);  
        System.out.println("활성 쓰레드 수: "+ g1.activeCount());  
    }  
}

출력:

활성 쓰레드 수: 2
실행 중인 쓰레드 이름: Thread-1
실행 중인 쓰레드 이름: Thread-2

23. public final void checkAccess()

이 메소드는 현재 쓰레드가 쓰레드를 수정할 수 있는 권한이 있는지를 확인한다.

예시:

public class JavaCheckAccessExp extends Thread {    
    public void run() {  
        System.out.println(Thread.currentThread().getName()+" 실행 완료");  
    }  

    public static void main(String arg[]) throws InterruptedException, SecurityException {   
        JavaCheckAccessExp thread1 = new JavaCheckAccessExp();    
        JavaCheckAccessExp thread2 = new JavaCheckAccessExp();    
        thread1.start();  
        thread2.start();  
        thread1.checkAccess();    
        System.out.println(t1.getName() + "에게 접근 권한 있음");    
        thread2.checkAccess();    
        System.out.println(t2.getName() + "에게 접근 권한 있음");    
    }    
}

출력:

Thread-0에게 접근 권한 있음
Thread-1에게 접근 권한 있음
Thread-0 실행 완료
Thread-1 실행 완료

24. public static boolean holdsLock(Object obj)

현재 실행 중인 쓰레드가 지정된 객체에 대한 모니터 락을 소유하는지 확인하는 메소드이다.

예시:

public class JavaHoldLockExp implements Runnable {  
    public void run() {  
        System.out.println("현재 실행 중인 쓰레드: " + Thread.currentThread().getName());  
        System.out.println("쓰레드가 락을 소유 중인가? " + Thread.holdsLock(this));  
        synchronized (this) {  
            System.out.println("쓰레드가 락을 소유 중인가? " + Thread.holdsLock(this));  
        }  
    }  

    public static void main(String[] args) {  
        JavaHoldLockExp g1 = new JavaHoldLockExp();  
        Thread thread1 = new Thread(g1);  
        thread1.start();  
    }  
}

출력:

현재 실행 중인 쓰레드: Thread-0
쓰레드가 락을 소유 중인가? false
쓰레드가 락을 소유 중인가? true

자바에서의 멀티스레딩 시작하기

멀티스레딩을 시작할 때, 자바에서는 새롭게 생성된 스레드를 시작하기 위해 start() 메서드를 사용합니다.

새로운 스레드는 새로운 콜스택으로 시작됩니다.
스레드는 New 상태에서 Runnable 상태로 이동합니다.
스레드가 실행할 기회를 얻으면, 해당 스레드의 목표 run() 메서드가 실행됩니다.

Thread Class를 확장한 자바 스레드 예제

class Multi extends Thread {  
    public void run() {  
        System.out.println("스레드가 실행 중입니다...");  
    }  

    public static void main(String args[]) {  
        Multi thread1 = new Multi();  
        thread1.start();  
    }  
} 

출력 결과:

스레드가 실행 중입니다...

Runnable 인터페이스를 구현한 자바 스레드 예제

class Multi3 implements Runnable {  
    public void run() {  
        System.out.println("스레드가 실행 중입니다...");  
    }  

    public static void main(String args[]) {  
        Multi3 m1 = new Multi3();  
        Thread thread1 = new Thread(m1);  
        thread1.start();  
    }  
}  

출력 결과:

스레드가 실행 중입니다...

마무리

이것이 자바에서의 멀티스레딩에 대한 기본적인 이해입니다. 이 글이 여러분께 자바에서의 멀티스레딩을 이해하는 데 도움이 되었기를 바랍니다.

Leave a Comment