Javaのデータの共有、スレッドの同期と相互排他をマルチスレッド

EDITORIAL

この記事は、Java、スレッドの同期の複数のスレッド間で共有データへのシステム、例えば、ジェーンのV二つの方法を発券することにより組み込まれています。記事では、多くの欠点を有していてもよく、理解ギャングのコメントを歓迎してください。

本明細書で使用する場合、事

  1. ジャワ
  2. 日食2019から11

1.マルチスレッド共有データ

1.1共有Runnableを

  実行の複数のスレッドが実行可能インターフェースクラスオブジェクトを共有する方法を採用することができる同じコンテンツがメンバ変数のRunnableとしてデータ、共用データ・オブジェクトを共有します。
  ここでは、例えば、切符売り場、複数のスレッドごとにチケットをチケットシステム、複数のスレッドが投票変数の数よりも多くを共有しています。

class TicketRunnable implements Runnable{
	private int num;
	
	public TicketRunnable(int num) {
		this.num=num;
	}
	@Override
	public void run() {
		for(int i=0;i<5;i++) {	//出售5张票
			if(num>0) {
				num--;
				System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
			}else {
				System.out.println(Thread.currentThread().getName()+":暂时无余票");
			}
		}
	}
}
public class 多线程共享数据 {
	public static void main(String[] args) {
		Runnable runnable = new TicketRunnable(8);	//初始化8张余票
		new Thread(runnable,"武汉售票点").start();
		new Thread(runnable,"北京售票点").start();
	}
}

1.2カプセル化データオブジェクト

  方法は、共有Runnableオブジェクトは、同じ変数の操作を共有するために使用することができる複数のスレッドを実行している場合、この方法は、共有データオブジェクトにパッケージ化することができる異なる動作を行うのに適していない場合、オブジェクトは、複数のスレッドで共有されています。
  チケットシステムには、例えば、実行還付のスレッド、実行チケットのスレッド。

class Ticket{
	private int num;
	public Ticket(int num) {
		this.num=num;
	}
	public void sell() {
		if(num>0) {
			num--;
			System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
		}else {
			System.out.println(Thread.currentThread().getName()+":暂时无余票");
		}
	}
	public void returned() {
		num++;
		System.out.println(Thread.currentThread().getName()+":退票1张,余票"+num);
	}
}
public class 多线程共享数据 {
	public static void main(String[] args) {
		Ticket ticket = new Ticket(8);	//初始化为8张票
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i=0;i<8;i++) {
					ticket.sell();//售票
				}
			}
		},"售票处").start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i=0;i<8;i++) {
					ticket.returned();//退票
				}
			}
		},"退票处").start();
	}
}

2.スレッド同期と相互排他

問題2.1上記のコード

同期して実行可能な共有オブジェクト・インプリメンテーション、例えば、プログラムを実行し、結果は次の通りであります:

武汉售票点:售票1张,余票6
武汉售票点:售票1张,余票5
北京售票点:售票1张,余票6
武汉售票点:售票1张,余票4
武汉售票点:售票1张,余票2
北京售票点:售票1张,余票3
北京售票点:售票1张,余票0
北京售票点:暂时无余票
北京售票点:暂时无余票
武汉售票点:售票1张,余票1

  得票数の初期値は、我々は、減少を開始する7から利用できる多くないチケットを操作して結果を表示するために8に設定されたが、6月から、そして減少されていません。チケット武漢票マイナス時点1が出力されていないために問題が発生し、北京のチケットも6回出力され、1票の数を減らすことができます。読み出しデータが出力されていないため、出力を減少させることによって、別のスレッドは、チケットの出力を実行しません。TicketRunnable run()として修正わずかに修正された方法、

	@Override
	public void run() {
		for(int i=0;i<5;i++) {	//出售5张票
			synchronized (this) {
				if(num>0) {
					num--;
					System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
				}else {
					System.out.println(Thread.currentThread().getName()+":暂时无余票");
				}
			}
		}
	}

この場合、出力は、同期ロックとしてコードブロックに同期して、同期操作の値の値を変更する、それがスクランブルされず、高い順に番組コンテンツであり、出力は私が間違ってチケット現れます。

2.2同期と相互排他

1.相互に排他的では何ですか?
多くのコンピュータリソースが限られているでは、この限られたリソースは、重要なリソースと呼ばれています。複数のプロセスがグラブが実行されませんしませんでした、あなたが実行をつかむことができ、同じ重要なリソースを競います。間接的な関係のための競争は、プロセスの相互に排他的な、重要なリソースの制約です。例えば、複数のスレッドがリソースを印刷するプリンタの競合、プロセス間ミューテックスが形成されています。

2.同期とは何ですか?
同期は、タスクを完了するために、複数の相互に関連するスレッドの協力の調整で、互いの間にいくつかの制約があり、実行の順序は、多くの場合、注文しています。同期が直接そのような供給やマーケティングシステムとプロセスとの関係を規制され、次いで、送達および販売のプロセスは同期関係を形成するためのプロセス、倉庫は全電源である場合に、倉庫の出荷が空でない停止する必要があります。

同期を達成するために、同期2.3

この方法は、同期、静的メソッドとコードブロックを修正するために使用することができます

//对象锁,修饰方法
synchronized void a() {

}
//类锁,修饰静态方法
synchronized static void b() {

}
void c() {
	//对象锁,修饰代码块
	synchronized (this) {
			
	}
	//类锁,修饰代码块
	synchronized (Ticket.class) {

	}	
}

2.4 ReentrantLockの同期

1.使用

ReentrantLock lock = new ReentrantLock();
lock.lock();	//加锁
lock.unlock();	//解锁

発券上記の同期を達成するために2

class TicketRunnable implements Runnable{
	private int num;
	ReentrantLock lock = new ReentrantLock();
	
	public TicketRunnable(int num) {
		this.num=num;
	}
	@Override
	public void run() {
		for(int i=0;i<5;i++) {	//出售5张票
			lock.lock();
			if(num>0) {
				num--;
				System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
			}else {
				System.out.println(Thread.currentThread().getName()+":暂时无余票");
			}
			lock.unlock();
		}
	}
}
public class 多线程共享数据 {
	public static void main(String[] args) {
		Runnable runnable = new TicketRunnable(8);	//初始化8张余票
		new Thread(runnable,"武汉售票点").start();
		new Thread(runnable,"北京售票点").start();
	}
}

3.まとめ

同期実装はこの点を理解することがやや困難同期又は相互に排他的であり、インターネットはまた、ミューテックスが同期していることを述べている、同期実装は、修正されたコンテンツの同期です。コメントは歓迎曖昧がありますが、私は返事を見るでしょう。この記事では、欠陥は私を修正すること自由に感じなさい何であるか、以上です。

公開された42元の記事 ウォン称賛22 ビュー7985

おすすめ

転載: blog.csdn.net/nineya_com/article/details/104059103