引言

  当多个线程操作共享的数据时,共同修改该数据。可能出现,当第1个线程想操作A状态的数据时,发现已经被第二个线程修改为了B状态,于是无法完成本想完成的任务。即:存在两个或者两个以上的线程对象共享同一个资源。
  也存在操作共享资源线程代码有多条导致多线程安全出现问题。

解决

  1、利用同步代码块

public class Ticket implements Runnable{
	private int number = 100;	
	//在成员位置定义锁对象
	private Object lock = new Object();
	@Override
	public void run() {
		//车站不停地在卖票
		while(true){
			//将一个完整动作使用synchronized同步代码块包裹
			synchronized(lock) //锁对象自行设置,同一即可{
				//线程暂停20毫秒
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				//有票就买票
				if(number>0){
					String threadName = Thread.currentThread().getName();
					System.out.println(threadName+"正在销售第"+(number)+"张票");					
					number--;
				}else{
					//没有票,就跳出循环,不再卖票
					break;
				}
			}
			
		}
	}
}

  2、利用同步方法
    2.1动态同步

//调用即可同步运行
public synchronized void sell(){
	//线程暂停20毫秒
	try {
		Thread.sleep(20);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	
	//有票就买票
	if(number>0){
		String threadName = Thread.currentThread().getName();
		System.out.println(threadName+"正在销售第"+(number)+"张票");		
		number--;
	}
}

    2.2静态同步

//该锁的对象为 类.class (共享使用一定注意,否则锁不住)
public static synchronized void sell(){
	//线程暂停20毫秒
	try {
		Thread.sleep(20);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	
	//有票就买票
	if(number>0){
		String threadName = Thread.currentThread().getName();
		System.out.println(threadName+"正在销售第"+(number)+"张票");	
		number--;
	}
}