线程的同步——锁机制 synchronized

异步编程模型:两个线程之间谁也不等谁

同步编程模型:当一个线程必须等另外一个线程执行结束之后,线程才能执行

 

为什么引入线程同步?

为了数据的安全(暂时不考虑效率),线程同步使程序变了单线程。

什么情况下引入线程的同步?

1.多线程环境

2.多线程环境共享同一个数据

3.共享的数据涉及到修改操作

模拟银行的存款业务,引入线程的同步

 

对象过来找synchronized关键字,找到this锁就执行,找不到就等

 

public static void main(String[] args) {
		Account act = new Account("Account01",5000.0);
		
		Processor010 p = new Processor010(act);
		//将两个线程合并为一个线程
		Thread t1 = new Thread(p);
		Thread t2 = new Thread(p);
		t1.start();
		t2.start();
		
		
	}
}
class Account{
	private String name;
	private double balance;
	
	public Account(String name, double balance) {
		super();
		this.name = name;
		this.balance = balance;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getBalance() {
		return balance;
	}
	public void setBalance(double balance) {
		this.balance = balance;
	}
	//取款方法
	public void Withdraw(double money) {
					 
		/*t1线程执行的到此处,遇到了synchronized关键字,就回去找this对象的对象锁,如果找到则进入同步语句块中执行程序,当同步语句块中的代码执行结束之后,
		 *t1归还this的对象锁。
		 *
		 *在t1执行同步语句块的代码过程中,如果t2也过来执行以下代码,也遇到了synchronnized关键字,所以也去找this的对象锁,但是该对象的对象锁被t1持有,只能等待this对象的归还
		 *
		 * */
		
		
					//共享对象
		synchronized(this) {
		double after  = balance - money;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
		this.setBalance(after);	
	}
		}
}
class Processor010 implements Runnable{
	Account act;
	Processor010(Account act){
		this.act = act;
	}
	public void run() {
		act.Withdraw(10000.0);
		System.out.println("取款成功:余额"+act.getBalance());
	}
}
//关键字添加在成员方法上,线程拿走的也是this的锁
	public synchronized void Withdraw(double money) {
					 
		/*t1线程执行的到此处,遇到了synchronized关键字,就回去找this对象的对象锁,如果找到则进入同步语句块中执行程序,当同步语句块中的代码执行结束之后,
		 *t1归还this的对象锁。
		 *
		 *在t1执行同步语句块的代码过程中,如果t2也过来执行以下代码,也遇到了synchronnized关键字,所以也去找this的对象锁,但是该对象的对象锁被t1持有,只能等待this对象的归还
		 *
		 * */
		
		double after  = balance - money;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
		this.setBalance(after);	
	}

 

两种方法之下,第一种,放在下面的语句块中可以精确的去控制

 

 

synchronized详解01

public static void main(String[] args) throws InterruptedException {
	myclass mc = new myclass();
	Processor p = new Processor(mc);
	Thread t1 = new Thread(p);
	t1.setName("t1");
	Thread t2 = new Thread(p);
	t2.setName("t2");
	
	t1.start();
	//延迟
	Thread.sleep(1000);
	t2.start();
	
}
}
class Processor implements Runnable{
	myclass mc; 
	Processor(myclass mc){
		this.mc = mc;
	}
	
	public void run() {
		if(Thread.currentThread().getName().equals("t1")) {
			mc.m1();
		}
		if(Thread.currentThread().getName().equals("t2")) {
			mc.m2();
		}
	}
}
class myclass {
	public synchronized void m1() {
		try {
			Thread.sleep(100000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("m1");
	}
	
	//m2方法的执行不需要等m1方法的结束,没有synchronized
	/*public void m2() {
		System.out.println("m2");
	}*/
	public synchronized void m2() {
		System.out.println("m2");
	}
}

 

 

类锁——类只有一个,所以锁是类级别的,只有一个

static 中,用的是类锁,和对象锁无关,所以依然会synchronized等

public static void main(String[] args) throws InterruptedException {
		myclass01 mc1 = new myclass01();
		myclass01 mc2 = new myclass01();
		
		Thread t1 = new Thread(new Processor0(mc1));
		Thread t2 = new Thread(new Processor0(mc2));//等,下面用的是类锁,和对象锁无关
		
		t1.setName("t1");
		Thread.sleep(1000);
		
		t2.setName("t2");
		
		
		
	}
}
class Processor0 implements Runnable{
	myclass01 mc ;
	Processor0(myclass01 mc){
		this.mc = mc;
	}
	public void run() {
		if("t1".equals(Thread.currentThread().getName())) {
			 mc.m1();
		}
		if("t2".equals(Thread.currentThread().getName())) {
			 mc.m2();
		}
	}
}
class myclass01 {
	public synchronized static void m1() {
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("m1");
	}
	//不等,因为没有synchronized
	/*public static void m2() {
		System.out.println("m2");
	}*/
	//等,程序执行需要类锁,而类锁只有一个
	public synchronized static void m2() {
		System.out.println("m2");
	}
}

死锁

 

	public static void main(String[] args) {
		Object o1 = new Object();
		Object o2 = new Object();
		
		Thread t1 = new Thread(new T1(o1,o2));
		Thread t2 = new Thread(new T2(o1,o2));
		t1.start();
		t2.start();
		
	}
}

class T1 implements Runnable{
	Object o1;
	Object o2;
	T1(Object o1,Object o2){
		this.o1 = o1;
		this.o2 = o2;
		
	}
	public void run() {
		synchronized(o1) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			synchronized(o2) {
				
			}
		}
		
	}
}
class T2 implements Runnable{
	Object o1;
	Object o2;
	T2(Object o1,Object o2){
		this.o1 = o1;
		this.o2 = o2;
		
	} 
	public void run() {
		synchronized(o2) {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			synchronized(o1) {
				
			}
		}
		
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值