同步和死锁

同步

多线程数据不同步的三种解决方法

需求:深圳罗湖火车站目前正在出售车票,共有100张票,而它有3个售票窗口售票
解决办法:
1.同步代码块
2.同步方法
3.同步锁

可能出现线程安全的问题的情况:
1.存在多线程环境
2.多个线程共享同一份数据
3.多个线程操作同一份数据并且共享数据做了修改
4.存在多条语句操作共享数据

在多线程环境下,存在多条语句操作共享数据,并且对数据做了修改的操作,那么必定会出现线程安全问题
解决办法: 将多条操作共享数据的语句 包裹起来,同步锁

//多线程数据不同步的三种解决方法
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//SellThread1 st = new SellThread1();//方法1
		//SellThread2 st = new SellThread2();//方法2
		SellTh3 st = new SellTh3();//方法3
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(st);
		Thread t3 = new Thread(st);
		t1.setName("窗口A");
		t2.setName("窗口B");
		t3.setName("窗口C");
		
		t1.start();
		t2.start();
		t3.start();
	}
方式1:同步代码块:

enum MyLook{LOCK}//定义枚举,lock是静态final类对象
class SellThread1 implements Runnable{
	private int tickets=100;//不用加static因为只创建了一个接口子类对象
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			synchronized(MyLook.LOCK){//此处放一个静态final对象
				if(tickets>0){
					try {
						Thread.sleep(100L);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+"还剩:"+(--tickets));
				}
			}
		}
	}
}
方法2:同步方法

格式:
public synchronized 返回值 方法名(参数列表) {
//需要同步的代码块
}

如果锁对象是this,就可以考虑使用同步方法。

如果方式静态方法, 当前类对应的字节码文件对象作锁
Class c = SellTicketThread.class
静态方法和默认的类字节码文件做对象可以使用Thread的子类来实现功能:

(只有这种情况下我才会用Thread,因为是Thread的字节码文件做锁)

class SellThread2 implements Runnable{
	private int tis=100;
	//private static int tis=100;//静态
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			sellt();
		}
	}
	//静态public static synchronized void sellt()
	public synchronized void sellt(){
		if(tis>0){
			try {
				Thread.sleep(100L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+(--tis));
		}
	}
}

方法二的Thread:

/*class SellTicketThread extends Thread {

private static int tickets = 100;

@Override
public void run() {
	while (true) {
		sellTicket();
	}
}

public static synchronized void sellTicket() {
	if (tickets > 0) {
		try {
			Thread.sleep(100L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票");
	}
}
}*/
方法3 创建锁对象

Lock lock=new ReentrantLock();//创建锁对象

//方法三:加锁,创建锁对象
class SellTh3 implements Runnable{
	private int tis=100;
	Lock lock=new ReentrantLock();//创建锁对象
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			lock.lock();
			if(tis>0){
				try {
					Thread.sleep(100L);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+(--tis));
			}
			lock.unlock();
		}
	}	
}

死锁:

死锁:指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象。

  • 代码演示死锁现象。
  • 总共有四种情况会死锁
public class DeadThradDemo {
	public static void main(String[] args) {
		DieLock dl1 = new DieLock(true);
		DieLock dl2 = new DieLock(false);

		dl1.start();
		dl2.start();
	}
}

class DieLock extends Thread {
	private boolean flag;

	public DieLock() {
	}

	public DieLock(boolean flag) {
		this.flag = flag;
	}

	@Override
	public void run() {
		if (flag) {
			// dl1进来
			synchronized (TestLock.LOCKA) {
				System.out.println("if 语句中 LockA锁"); 
				synchronized (TestLock.LOCKB) {
					System.out.println("if 语句中 LockB锁");
				}
			}
		} else {
			// dl走else
			synchronized (TestLock.LOCKB) {
				System.out.println("else 语句中 lockB锁");
				synchronized (TestLock.LOCKA) {
					System.out.println("else 语句中 lockA锁");
				}
			}
		}
	}
}

class TestLock {
	public static final Object LOCKA = new Object();
	public static final Object LOCKB = new Object();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值