Java 동시/다중 스레드

10483 단어 java 병발
Java 다중 스레드
스레드를 구현하는 두 가지 방법:
a. Thread 클래스를 상속하고 start()가 시작됩니다.
b. Runnable 인터페이스를 실현하고run 방법을 실현한다.
 
1. 기본 스레드
package com.sam.thread; public class SimpleThread extends Thread {     private int countDown = 5;     private static int threadCount = 0;     public SimpleThread() {         super(""+++threadCount);//store the thread name         start();     }     public String toString() {         return "#"+ getName() + ": "+ countDown;     }     public void run() {         while (true) {             System.out.println(this);             if (--countDown == 0)                 return;         }     }     public static void main(String[] args) {         for (int i = 0; i < 5; i++) {             new SimpleThread();         }     } }
package com.sam.thread;

public class SimpleThread extends Thread {
	private int countDown = 5;
	private static int threadCount = 0;

	public SimpleThread() {
		super(" " + ++threadCount); // store the thread name
		start();
	}

	public String toString() {
		return "#" + getName() + ": " + countDown;
	}

	public void run() {
		while (true) {
			System.out.println(this);
			if (--countDown == 0)
				return;
		}
	}

	public static void main(String[] args) {
		for (int i = 0; i < 5; i++) {
			new SimpleThread();
		}
	}
}

결과:
# 1: 5
# 1: 4
# 1: 3
# 1: 2
# 1: 1
# 3: 5
# 3: 4
# 3: 3
# 3: 2
# 3: 1
# 2: 5
# 5: 5
# 5: 4
# 5: 3
# 5: 2
# 5: 1
# 2: 4
# 2: 3
# 2: 2
# 2: 1
# 4: 5
# 4: 4
# 4: 3
# 4: 2
# 4: 1
 
 
 
2.yield(), 다른 스레드가 CPU를 사용하도록 양보하면 결과를 더욱 균형 있게 할 수 있다.
package com.sam.thread;

public class YieldThread extends Thread {
	private int countDown = 5;
	private static int threadCount = 0;

	public YieldThread() {
		super(" " + ++threadCount); // store the thread name
		start();
	}

	public String toString() {
		return "#" + getName() + ": " + countDown;
	}

	public void run() {
		while (true) {
			System.out.println(this);
			if (--countDown == 0)
				return;
			yield();
		}
	}

	public static void main(String[] args) {
		for (int i = 0; i < 5; i++) {
			new YieldThread();
		}
	}
}

결과:
# 1: 5
# 2: 5
# 3: 5
# 1: 4
# 2: 4
# 5: 5
# 3: 4
# 1: 3
# 5: 4
# 3: 3
# 1: 2
# 5: 3
# 3: 2
# 1: 1
# 5: 2
# 4: 5
# 3: 1
# 5: 1
# 2: 3
# 4: 4
# 2: 2
# 2: 1
# 4: 3
# 4: 2
# 4: 1

 
3.sleep, 잠시 휴면 후 실행
package com.sam.thread;

public class SleepThread extends Thread {
	private int countDown = 5;
	private static int threadCount = 0;

	public SleepThread() {
		super(" " + ++threadCount); // store the thread name
		start();
	}

	public String toString() {
		return "#" + getName() + ": " + countDown;
	}

	public void run() {
		while (true) {
			System.out.println(this);
			if (--countDown == 0)
				return;
			try {
				sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		for (int i = 0; i < 5; i++) {
			new SleepThread();
		}
	}
}

결과:
# 1: 5
# 3: 5
# 2: 5
# 5: 5
# 4: 5
# 1: 4
# 2: 4
# 4: 4
# 3: 4
# 5: 4
# 1: 3
# 2: 3
# 3: 3
# 4: 3
# 5: 3
# 2: 2
# 4: 2
# 3: 2
# 1: 2
# 5: 2
# 1: 1
# 2: 1
# 4: 1
# 3: 1
# 5: 1

 
4. 우선순위 setPriority(),
package com.sam.thread;

public class PriorityThread extends Thread {
	private int countDown = 5;
	private static int threadCount = 0;

	public PriorityThread(int priority) {
		super(" " + ++threadCount); // store the thread name
		setPriority(priority);
		start();
	}

	public String toString() {
		return "#" + getName() + ": " + countDown;
	}

	public void run() {
		while (true) {
			System.out.println(this);
			if (--countDown == 0)
				return;			
		}
	}

	public static void main(String[] args) {
		new PriorityThread(Thread.MAX_PRIORITY);
		for (int i = 0; i < 5; i++) {
			new PriorityThread(Thread.MIN_PRIORITY);
		}
	}
}

결과: 우선 순위가 높은 선행 실행
# 1: 5
# 1: 4
# 1: 3
# 1: 2
# 1: 1
# 3: 5
# 3: 4
# 3: 3
# 3: 2
# 3: 1
# 5: 5
# 5: 4
# 5: 3
# 5: 2
# 5: 1
# 2: 5
# 2: 4
# 2: 3
# 2: 2
# 2: 1
# 4: 5
# 4: 4
# 4: 3
# 6: 5
# 6: 4
# 6: 3
# 6: 2
# 6: 1
# 4: 2
# 4: 1

 
5. 백그라운드 스레드(daemon)
모든 비백엔드 라인이 끝나면 라인이 종료됩니다.예를 들어: 어느 순간 라인이sleep에 의해 종료되었습니다. 프로그램이 종료되었습니다.
package com.sam.thread;

public class DaemonThread extends Thread {
	private int countDown = 5;
	private static int threadCount = 0;

	public DaemonThread() {
		super(" " + ++threadCount); // store the thread name
		setDaemon(true);
		start();
	}

	public String toString() {
		return "#" + getName() + ": " + countDown;
	}

	public void run() {
		while (true) {
			System.out.println(this);
			if (--countDown == 0)
				return;
			try {
				sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	public static void main(String[] args) {
		for (int i = 0; i < 5; i++) {
			new DaemonThread();
		}
	}
}

결과:
# 1: 5
# 3: 5
# 5: 5
# 4: 5
# 2: 5

 
6. join() 및 interrupt()
package com.sam.thread;

class A extends Thread {
	public A() {
		start();
	}
	public void run() {
		try {
			System.out.println("A started.");
			sleep(1000);
		} catch (InterruptedException e) {
			System.out.println("Sleep interrupted");
		}
	}
}

public class JoinThread extends Thread {
	A a;
	public JoinThread(A a) {
		this.a = a;
		start();
	}
	public void run() {
	
		try {
			a.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("JoinThread started.");
	}
	public static void main(String[] args) {
		A a = new A();
		JoinThread jt = new JoinThread(a);
		a.interrupt();
	}
}

결과:
A started.
Sleep interrupted
JoinThread started.

 
7. Runnable 커넥터
package com.sam.thread;

public class RunnableThread implements Runnable {

	private int countDown = 5;

	public String toString() {
		return "#" + Thread.currentThread().getName() + ": " + countDown;
	}

	@Override
	public void run() {
		while (true) {
			System.out.println(this);
			if (--countDown == 0)
				return;
		}
	}

	public static void main(String[] args) {
		for (int i = 1; i <= 5; i++) {
			new Thread(new RunnableThread(), "" + i).start();
		}
	}
}

runnable 인터페이스 자체는 라인이 없는 특성입니다. 실행하시겠습니까? 아니면 단독 Thread 대상을 만드시겠습니까?
 
8. 리소스에 대한 잘못된 액세스
package com.sam.thread;

public class AlwaysEven {
	int i;

	void next() {
		i++;
		i++;
	}

	int get() {
		return i;
	}

	public static void main(String[] args) {
		final AlwaysEven ae = new AlwaysEven();
		new Thread() {
			public void run() {
				while (true) {
					int j = ae.get();
					if (j % 2 != 0) {
						System.out.println(j);
						System.exit(0);
					}
				}
			}
		}.start();
		while (true) {
			ae.next();
		}
	}
}

결과:
1501

 
9. 공유 자원 경쟁 해결
모든 공유 자원에 접근하는 방법에synchronized를 추가해야 합니다. 그렇지 않으면 이 자물쇠를 무시하는 방법이 있습니다.
package com.sam.thread;

public class AlwaysEven {
	int i;

	synchronized void next() {
		i++;
		i++;
	}

	synchronized int get() {
		return i;
	}

	public static void main(String[] args) {
		final AlwaysEven ae = new AlwaysEven();
		new Thread() {
			public void run() {
				while (true) {
					int j = ae.get();
					if (j % 2 != 0) {
						System.out.println(j);
						System.exit(0);
					}
				}
			}
		}.start();
		while (true) {
			ae.next();
		}
	}
}

 
10. volatile
컴파일러의 최적화를 금지하고, 라인은 이 대상의 개인 복사를 보존할 수 없으며, 효율에 영향을 미친다.
 
11. 임계구
다중 루틴 접근 방지 방법의 일부 코드입니다.
synchronized(syncObject) {
    // This code can only be access
    // by one thread at a time
}

 
12. 스레드의 상태
새로 만들기
준비(Runnable)
사망(Dead)
차단(Blocked)
 
13. notify()
wait ()의 라인을 깨웁니다.
 
zz

좋은 웹페이지 즐겨찾기