현재 버전

자바 쓰레드코딩에 대해 질문이있어요.


제 코드는, 똑같은 코드인데 실행할때마다 다른결과가 나오구요,

상대방의 코드는 여러번 실행해도 모두 똑같은결과가 나와요.


무슨차이인지 전혀 납득이안가서 질문올리게되었어요.


원래 쓰래드코딩이란게 미묘하게 누가먼저실행되냐에따라 다르기때문에,

누가먼저실행되더라도 같은결과를 낼 수 있도록 코딩해야하는거같은대..


test.Water.java (synchronized만 테스트해보려고 간단해요)

public class Water 
{
	private int water;

	public int getWater()
	{
		return water;
	}
}


test.Test.java

public class Test
{
	public static void main(String[] args) throws InterruptedException
	{
		Water water = new Water();
		ProducerThread3 pt = new ProducerThread3(water);
		ConsumerThread3 ct = new ConsumerThread3(water);
		
		pt.setConsumerThread(ct);
		ct.setProducerThread(pt);
		
		pt.start();
		ct.start();
	}
}


쓰레드1 - 생산자쓰래드

public class ProducerThread3 extends Thread
{
	private Water water;
	private Thread consumerThread;

	public ProducerThread3(Water water)
	{
		setName("생산자 스레드");
		this.water = water;
	}

	public void setConsumerThread(Thread consumerThread)
	{
		this.consumerThread = consumerThread;
	}

	@Override
	public void run() 
	{
		synchronized(water)
		{
			water.getWater();
			System.out.println("Producer 동기화블록 - 생산자 상태 : " + consumerThread.getState());
		}
		
		System.out.println("Producer 종료 - 생산자 상태 : " + consumerThread.getState());
	}
}


쓰레드2 - 소비자쓰레드

	@Override
	public void run() 
	{
		synchronized(water)
		{
		}

		System.out.println("Consumer Thread 종료");
	}

다른거 같아서 run()만 올렸어요.


그리고 실행결과가..

이런식으로, 아주 다양하게 나왔어요. 그래서 아주 황당한상태인데,

(wait(), notify()가 이해가안되서 이것부터 공부하다 나온 테스트코드에요)


구글링하다 찾은 다른분의 코드는..

    public class ThreadB extends Thread{
        int total;
        @Override
        public void run(){
            synchronized(this){
                for(int i=0; i<5 ; i++){
                    System.out.println(i + "를 더합니다.");
                    total += i;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                notify();
            }
        }
    }


    public class ThreadA {
        public static void main(String[] args){
            ThreadB b = new ThreadB();
            b.start();

            synchronized(b){
                try{

                    System.out.println("b가 완료될때까지 기다립니다.");
                    b.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }

                System.out.println("Total is: " + b.total);
            }
        }
    }


이분의 코드는 아주 멀쩡해요. 아무리실행해도 항상같은결과에요.

무슨차이가있는거에요?...


수정 이력

2019-03-20 16:59:23 에 아래 내용에서 변경 됨 #2

제 코드는, 똑같은 코드인데 실행할때마다 다른결과가 나오구요,

상대방의 코드는 여러번 실행해도 모두 똑같은결과가 나와요.


무슨차이인지 전혀 납득이안가서 질문올리게되었어요.


원래 쓰래드코딩이란게 미묘하게 누가먼저실행되냐에따라 다르기때문에,

누가먼저실행되더라도 같은결과를 낼 수 있도록 코딩해야하는거같은대..


test.Water.java (synchronized만 테스트해보려고 간단해요)

public class Water 
{
	private int water;

	public int getWater()
	{
		return water;
	}
}


제코드)

test.Test.java

public class Test
{
	public static void main(String[] args) throws InterruptedException
	{
		Water water = new Water();
		ProducerThread3 pt = new ProducerThread3(water);
		ConsumerThread3 ct = new ConsumerThread3(water);
		
		pt.setConsumerThread(ct);
		ct.setProducerThread(pt);
		
		pt.start();
		ct.start();
	}
}


쓰레드1 - 생산자쓰래드

public class ProducerThread3 extends Thread
{
	private Water water;
	private Thread consumerThread;

	public ProducerThread3(Water water)
	{
		setName("생산자 스레드");
		this.water = water;
	}

	public void setConsumerThread(Thread consumerThread)
	{
		this.consumerThread = consumerThread;
	}

	@Override
	public void run() 
	{
		synchronized(water)
		{
			water.getWater();
			System.out.println("Producer 동기화블록 - 생산자 상태 : " + consumerThread.getState());
		}
		
		System.out.println("Producer 종료 - 생산자 상태 : " + consumerThread.getState());
	}
}


쓰레드2 - 소비자쓰레드

	@Override
	public void run() 
	{
		synchronized(water)
		{
		}

		System.out.println("Consumer Thread 종료");
	}

다른거 같아서 run()만 올렸어요.


그리고 실행결과가..

이런식으로, 아주 다양하게 나왔어요. 그래서 아주 황당한상태인데,

(wait(), notify()가 이해가안되서 이것부터 공부하다 나온 테스트코드에요)


구글링하다 찾은 다른분의 코드는..

    public class ThreadB extends Thread{
        int total;
        @Override
        public void run(){
            synchronized(this){
                for(int i=0; i<5 ; i++){
                    System.out.println(i + "를 더합니다.");
                    total += i;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                notify();
            }
        }
    }


    public class ThreadA {
        public static void main(String[] args){
            ThreadB b = new ThreadB();
            b.start();

            synchronized(b){
                try{

                    System.out.println("b가 완료될때까지 기다립니다.");
                    b.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }

                System.out.println("Total is: " + b.total);
            }
        }
    }


이분의 코드는 아주 멀쩡해요. 아무리실행해도 항상같은결과에요.

무슨차이가있는거에요?...

2019-03-20 16:54:13 에 아래 내용에서 변경 됨 #1

제 코드는, 똑같은 코드인데 실행할때마다 다른결과가 나오구요,

상대방의 코드는 여러번 실행해도 모두 똑같은결과가 나와요.


무슨차이인지 전혀 납득이안가서 질문올리게되었어요.


원래 쓰래드코딩이란게 미묘하게 누가먼저실행되냐에따라 다르기때문에,

누가먼저실행되더라도 같은결과를 낼 수 있도록 코딩해야하는거같은대..


test.Water.java (synchronized만 테스트해보려고 간단해요)

public class Water 
{
	private int water;

	public int getWater()
	{
		return water;
	}
}


제코드)

test.Test.java

public class Test
{
	public static void main(String[] args) throws InterruptedException
	{
		Water water = new Water();
		ProducerThread3 pt = new ProducerThread3(water);
		ConsumerThread3 ct = new ConsumerThread3(water);
		
		pt.setConsumerThread(ct);
		ct.setProducerThread(pt);
		
		pt.start();
		ct.start();
	}
}


쓰레드1 - 생산자쓰래드

public class ProducerThread3 extends Thread
{
	private Water water;
	private Thread consumerThread;

	public ProducerThread3(Water water)
	{
		setName("생산자 스레드");
		this.water = water;
	}

	public void setConsumerThread(Thread consumerThread)
	{
		this.consumerThread = consumerThread;
	}

	@Override
	public void run() 
	{
		synchronized(water)
		{
			water.getWater();
			System.out.println("Producer 동기화블록 - 생산자 상태 : " + consumerThread.getState());
		}
		
		System.out.println("Producer 종료 - 생산자 상태 : " + consumerThread.getState());
	}
}


쓰레드2 - 소비자쓰레드

	@Override
	public void run() 
	{
		synchronized(water)
		{
		}

		System.out.println("Consumer Thread 종료");
	}

다른거 같아서 run()만 올렸어요.


그리고 실행결과가..

이런식으로, 아주 다양하게 나왔어요. 그래서 아주 황당한상태인데,


구글링하다 찾은 다른분의 코드는..

    public class ThreadB extends Thread{
        int total;
        @Override
        public void run(){
            synchronized(this){
                for(int i=0; i<5 ; i++){
                    System.out.println(i + "를 더합니다.");
                    total += i;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                notify();
            }
        }
    }


    public class ThreadA {
        public static void main(String[] args){
            ThreadB b = new ThreadB();
            b.start();

            synchronized(b){
                try{

                    System.out.println("b가 완료될때까지 기다립니다.");
                    b.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }

                System.out.println("Total is: " + b.total);
            }
        }
    }


이분의 코드는 아주 멀쩡해요. 아무리실행해도 항상같은결과에요.

무슨차이가있는거에요?...