135_多线程(多线程的安全问题)

class TWindow implements Runnable{
	private int ticketNum =100;
	
	public void run(){
		while(true){
			if(ticketNum > 0)
				System.out.println(Thread.currentThread().getName()
				+" sale "+ ticketNum--);
		}
	}
}

class ThreadDemo{
	public static void main(String[] args){
		TWindow t = new TWindow();
		
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		Thread t4 = new Thread(t);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}



安全隐患:见附件截图
/*
通过分析发现,打印出0,-1,-2等错票

多线程的运行出现了安全问题

问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句
只执行一部分,还没执行完,另一个线程参与进来执行,导致共享
数据的错误。

解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程
中,其它线程不可以参与执行。

java对于多线程的安全问题提供了解决方式,就是同步代码块。
synchronized(对象)
{
	需要被同步的代码
}
对象如同锁,只有锁的线程可以在同步中执行。
没有锁的线程即使有cpu使用权,也进不去,因为没有锁。

同步的前提:
1.必须要有两个或两个以上的线程
2.必须是多个线程使用同一个锁

必须保证同步中只能有一个线程在运行

好处:解决了多线程的安全问题
弊端:多个线程需要判断锁,较为消耗资源

*/
class TWindow implements Runnable{
	private int ticketNum =100;
	Object obj = new Object();
	public void run(){
		while(true){
			sychronized(obj){
				if(ticketNum > 0){
					try{
						Thread.sleep(10);
					}
					catch(Exception e){
						
					}
					System.out.println(Thread.currentThread().getName()
					+" sale "+ ticketNum--);
				}
			}
		}
	}
}

class ThreadDemo{
	public static void main(String[] args){
		TWindow t = new TWindow();
		
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		Thread t4 = new Thread(t);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

猜你喜欢

转载自317324406.iteye.com/blog/2248874