【Java-45】基于Java的多线程并发控制处理——以抢票系统模拟为例

如下代码对同一份资源cattle,现在定义三个代理,也就是三个线程去访问,如果不加synchronized关键字加以控制就会出现最后还有一张票时候三者都操作导致得到0与-1,故需要加以并发控制,并发控制主要有两种,如下代码,一种是封锁方法,一种是封锁块

package My_Thread;

public class Get_Tackets {
	public static void main(String[] args) {
		//一个资源
		Cattle cattle=new Cattle();
		//三个代理
		Thread th1=new Thread(cattle,"小明");
		Thread th2=new Thread(cattle,"大脸妹");
		Thread th3=new Thread(cattle,"小九九");
		th1.start();
		th2.start();
		th3.start();
		
	}
}

class Cattle implements Runnable {
	private boolean tag = true;// 标记为了停止线程
	private int num=10;

	public void stops() {
		this.tag = false;
	}
	
	//不同步,有可能最后还有一张票时候三者都操作导致得到0与-1
	public void get_tcket0() {
		while (this.tag) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (this.num <= 0) {
				break;
			}
			else{
				System.out.println(Thread.currentThread().getName()+"抢到"+num--);
			}
		}
	}
	
	//同步方法
	public synchronized void get_tcket() {
		while (this.tag) {
			try {
				Thread.sleep(500);//一个线程内部延迟
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (this.num <= 0) {
				break;
			}
			else{
				System.out.println(Thread.currentThread().getName()+"抢到"+num--);
			}
		}
	}
	
	//同步块
	public void get_tcket2() {
		synchronized(this){
			if (this.tag) {
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if (this.num <= 0) {
					tag=false;
					//break;
					return;
				}
				else{
					System.out.println(Thread.currentThread().getName()+"抢到"+num--);

				}
			}
		}
		
	}
	@Override
	public void run() {
//		get_tcket();
		while(this.tag){
			get_tcket0();
		}
	}
	

}

猜你喜欢

转载自blog.csdn.net/weixin_42034217/article/details/86666885
今日推荐