Java 다중 스레드 - 스레드의 상호작용

10355 단어 java 다중 루틴
1. 라인 상호작용의 기초 지식인void notify(): 이 대상 모니터에서 기다리는 단일 라인을 깨웁니다.void notifyAll (): 이 대상 모니터에서 기다리는 모든 라인을 깨웁니다.void wait (): 다른 스레드가 이 대상의 notify () 방법이나 notify All () 방법을 호출할 때까지 현재 스레드를 기다립니다.물론 wait () 에는 두 가지 재부팅 방법이 있습니다:void wait (long timeout): 다른 라인이 이 대상의 notify () 방법이나 notify All () 방법을 호출하거나 지정한 시간을 초과할 때까지 현재 라인을 기다립니다.void wait(long timeout, int nanos): 다른 스레드가 이 대상의 notify () 방법이나 notify All () 방법을 호출하거나 다른 스레드가 현재 스레드를 중단하거나 실제 시간을 초과할 때까지 현재 스레드를 기다리게 합니다.
대기/알림에 대해 기억해야 할 관건은 동기화 코드 블록에서wait (), notify (), notify All () 방법을 호출해야 한다는 것이다.라인은 그 대상의 자물쇠를 가지고 있지 않으면 대상에서 기다리거나 알림을 할 수 없습니다.
wait(), notify(), notifyAll()은 모두 Object의 실례적인 방법입니다.모든 대상이 자물쇠를 가지고 있는 것과 같이, 모든 대상은 이 신호 (알림) 를 기다릴 수 있는 라인 목록을 가지고 있다.루틴은 실행 대상의wait () 방법을 통해 이 대기 목록을 얻을 수 있습니다.대상의 notify () 방법을 호출할 때까지 다른 명령을 실행하지 않습니다.만약 여러 개의 스레드가 같은 대상에서 기다린다면, 하나의 스레드만 선택해서 (어떤 순서로 실행될지 보장되지 않음) 계속 실행할 것입니다.만약 라인이 기다리지 않는다면, 어떠한 특수한 조작도 취하지 않을 것이다.
예.
package cn.thread;

/**
 *  1+2+3 ... +100 
 * 
 * @author  
 * @version 1.0 2013-7-23  10:06:04
 */
public class ThreadSum extends Thread {
    int total = 0;

    @Override
    public void run() {

        synchronized (this) {
            for (int i = 0; i < 101; i++) {
                total += i;
            }
            //( ) , ThreadInteractionTest 
            notify();
        }

    }
}
package cn.thread;

/**
 *  
 * 
 * @author  
 * @version 1.0 2013-7-23  10:04:11
 */
public class ThreadInteractionTest {
    public static void main(String[] args) {
        
        ThreadSum sum = new ThreadSum();
        //  
        sum.start();
        //  ThreadInteractionTest sum 。
        //  wait() notify() , ThreadInteractionTest 
        synchronized (sum) {
            try {
                System.out.println(" sum 。。。");
                //  ThreadInteractionTest 
                sum.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sum :" + sum.total);
        }
        
    }
}
 sum 。。。
sum :5050

주의: 대상에서wait () 방법을 호출할 때, 이 코드를 실행하는 라인은 대상에 있는 자물쇠를 즉시 포기합니다.그러나 notify () 를 호출할 때, 이 라인이 자물쇠를 포기한다는 것을 의미하지는 않습니다.만약 루틴이 동기화 코드를 완성하고 있다면, 루틴이 이동하기 전에 자물쇠를 포기하지 않을 것입니다.따라서 notify () 를 호출하면 이 자물쇠가 사용할 수 있다는 것을 의미하지 않습니다.두 번째, 여러 개의 루틴은 대상이 잠길 때 notifyAll () 를 사용합니다. 대부분의 경우, 대상을 기다리는 모든 루틴을 알려주는 것이 좋습니다.만약 이렇게 한다면, 대상에 notifyAll () 을 사용하여 이 대상에서 기다리는 모든 라인을 대기 구역에서 벗어나 실행 가능한 상태로 되돌릴 수 있습니다.
package cn.thread;

/**
 *  1+2+3 ... +100 
 * 
 * @author  
 * @version 1.0 2013-7-23  10:06:04
 */
public class ThreadSum2 extends Thread {
    int total = 0;

    @Override
    public void run() {

        synchronized (this) {
            for (int i = 0; i < 101; i++) {
                total += i;
            }
            //  
            notifyAll();
        }

    }
}
package cn.thread;


/**
 *  
 * 
 * @author  
 * @version 1.0 2013-7-23  10:04:11
 */
public class ThreadInteractionTest2 extends Thread{
    ThreadSum2 sum;
    
    public ThreadInteractionTest2(ThreadSum2 sum){
        this.sum=sum;
    }
    
    @Override
    public void run() {
        synchronized (sum) {
            try {
                System.out.println(" sum 。。。");
                //  ThreadInteractionTest 
                sum.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sum :" + sum.total);
        }
    }
    
    public static void main(String[] args) {
        ThreadSum2 sum = new ThreadSum2();
        
        //
        new ThreadInteractionTest2(sum).start();
        new ThreadInteractionTest2(sum).start();
        new ThreadInteractionTest2(sum).start();
        
        //  
        sum.start();
        
        
    }
}
 sum 。。。
 sum 。。。
 sum 。。。
sum :5050
sum :5050
sum :5050

synchronized와wait(), notify() 등의 관계에 대해 이야기하자. 1. synchronized가 있는 곳에는wait가 반드시 있는 것은 아니다. notify2,wait가 있고 notify가 있는 곳에는synchronized가 있어야 한다.이것은wait와notify가 라인류에 속하는 것이 아니라 모든 대상이 가지고 있는 방법이기 때문이다. 그리고 이 두 가지 방법은 모두 대상 자물쇠와 관련이 있고 자물쇠가 있는 곳에는synchronized가 있기 때문이다.또한 주의사항: notify와wait 방법을 함께 사용하려면 notify를 먼저 호출한 후에wait를 호출해야 합니다.wait를 호출하면 이 라인은currentthread가 아니기 때문입니다.

좋은 웹페이지 즐겨찾기