JAVA同時制御のいくつかの方法
5363 ワード
10枚の切符があれば、今3つの窓口(スレッド)で売る必要があります.コードは以下の通りです.
出力結果:
ticket = 10
ticket = 9
ticket = 8
ticket = 7
ticket = 7
ticket = 7
ticket = 6
ticket = 5
ticket = 6
ticket = 4
ticket = 4
ticket = 3
ticket = 2
ticket = 1
ticket = 2
10枚以上売れていることがわかりますので、同時制御を行います.
第1の方法は、同期キーを採用することです.
出力結果は次のとおりです.
ticket = 10
ticket = 9
ticket = 8
ticket = 7
ticket = 6
ticket = 5
ticket = 4
ticket = 3
ticket = 2
ticket = 1
これで複数の窓口で切符を売ることができ、正確に、
2.原子変数を用いてもよい
3.信号量Semaphoreを採用
4.ロック採用
5.スレッド内の変数の値が元の値に依存して更新されるため、volatileキーワードは使用できません.
package com.test.runnable;
class MyThread implements Runnable {
private int ticket = 10;
public void run() {
while (ticket > 0) {
System.out.println("ticket = " + ticket--);
try {
Thread.sleep(2000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
出力結果:
ticket = 10
ticket = 9
ticket = 8
ticket = 7
ticket = 7
ticket = 7
ticket = 6
ticket = 5
ticket = 6
ticket = 4
ticket = 4
ticket = 3
ticket = 2
ticket = 1
ticket = 2
10枚以上売れていることがわかりますので、同時制御を行います.
第1の方法は、同期キーを採用することです.
package com.test.runnable;
class MyThread implements Runnable {
private int ticket = 10;
synchronized public void run() {
while (ticket > 0) {
System.out.println("ticket = " + ticket--);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
出力結果は次のとおりです.
ticket = 10
ticket = 9
ticket = 8
ticket = 7
ticket = 6
ticket = 5
ticket = 4
ticket = 3
ticket = 2
ticket = 1
これで複数の窓口で切符を売ることができ、正確に、
2.原子変数を用いてもよい
package com.test.runnable;
import java.util.concurrent.atomic.AtomicInteger;
class MyThread implements Runnable {
private AtomicInteger ticket = new AtomicInteger(10);
synchronized public void run() {
while (ticket.get() > 0) {
System.out.println("ticket = " + ticket.getAndAdd(-1));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
3.信号量Semaphoreを採用
package com.test.runnable;
import java.util.concurrent.Semaphore;
class MyThread implements Runnable {
final Semaphore semp = new Semaphore(1);
private int ticket = 10;
public void run() {
//
try {
semp.acquire();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (ticket > 0) {
System.out.println("ticket = " + ticket--);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// ,
semp.release();
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
4.ロック採用
package com.test.runnable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class MyThread implements Runnable {
private Lock myLock = new ReentrantLock(); //
private int ticket = 10;
public void run() {
myLock.lock();
while (ticket > 0) {
System.out.println("ticket = " + ticket--);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// ,
myLock.unlock();
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
5.スレッド内の変数の値が元の値に依存して更新されるため、volatileキーワードは使用できません.
package com.test.runnable;
class MyThread implements Runnable {
//private volatile int ticket = 10;
private volatile int ticket = 10;
public void run() {
while (ticket > 0) {
System.out.println("ticket = " + ticket--);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}