java蛇皮多线程(终章)

  多线程同步


举个银行取钱的例子来说

public class ThreadTest13 {

	public static void main(String[] args) {
		Account account=new Account("叫我男神O(∩_∩)O",5000);
		Thread t1=new Thread(new Processor(account));
		Thread t2=new Thread(new Processor(account));
		t1.start();
		t2.start();
	}

}
//取款的线程
class Processor implements Runnable{
	//账户
	Account act;
	Processor(Account act){
		this.act=act;
	}
	
	public void run() {
		act.withdraw(1000);
		System.out.println(act.getActno()+"取款1000块成功,余额:"+act.getbalance());
		
	}
}
//账户
class Account{
	//属性
	private String actno;
	private double balance;
	//构造方法
	public Account() {}
	public Account(String actno,double balance) {
		this.setActno(actno);
		this.setbalance(balance);
	
	}
	//set and get
	public String getActno() {
		return actno;
	}
	public void setActno(String actno) {
		this.actno=actno;
	}
	public double getbalance() {
		return balance;
		
	}
	public void setbalance(double balance) {
		this.balance=balance;
		
	}
	//对外提供一个取款的方法
	public synchronized void withdraw(double money) {
		synchronized (this) {
			//把要同步的代码放到同步语句块
			/*
			 * 原理t1 和t2
			 * t1线程执行到此处,遇到的synchroized这个关键字,就回去找this对象锁
			 *如果找到了this对象锁,则进入同步语句块中执行程序,当同步语句块中代码执行结束,t1线程归还this对象锁。
			 *
			 * 在t1线程执行同步语句块过程中,如果t2线程也过来执行以下程序,也会遇到synchronzed关键字,所以也去找this对象锁,但是该对象锁被t1线程持有,只能在此处等待this对象锁的归还
			 */
			double after=balance-money;
			//更新
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
			this.setbalance(after);
			
		}
	}
	
}


关于synchronized(锁)的小方面



t1与t2共享一个资源时(同一个进程的线程是共享其进程的*内存和资源*

共享的内存是*堆内存和方法内存*  栈内存不共享,每个线程有自己的栈空间(一个线程一个栈))

public class ThreadTest14 {

	public static void main(String[] args) throws InterruptedException {
		// TODO 自动生成的方法存根
		MyClass mc =new MyClass();
		F a=new F(mc);//t1与t2共享一个mc
		Thread t1=new Thread(a);
		t1.setName("t1");
		Thread t2=new Thread(a);
		t2.setName("t2");
		t1.start();
		//保证t1先执行
		Thread.sleep(1000);
		t2.start();
		
	}

}
class F implements Runnable{
	MyClass mc;
	F(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(5000);
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
		System.out.println("m1...");
	}
//	public  void m2() {	  m2不需要等m1结束m2   没有synchronized关键字
//		System.out.println("m2....");
//	}
	public synchronized void m2(){//m2方法会等m1结束 t1和t2共享一个mc ,并且m1和m2都有synchronized
	System.out.println("m2......");
}
}
第一次m2没加synchronized关键字(没和m1公用一个茅坑)



第二次m2加了synchronized关键字(和m1共同享用一个茅坑)


对象锁(不止一个)


m2方法不会等m1方法结束  ,t1和t2不共享同一mc内存。


public class ThreadTest15 {

	public static void main(String[] args) throws Exception {
		
		MyClass01 mc1 = new MyClass01();
		MyClass01 mc2 = new MyClass01();
		
		B b1 = new B(mc1);
		B b2 = new B(mc2);
		//*t1与t2 不共享同一mc内存*
		Thread t1 = new Thread(b1);
		t1.setName("t1");
		Thread t2 = new Thread(b2);
		t2.setName("t2");
		
		t1.start();
		//保证t1先执行
		Thread.sleep(1000);
		t2.start();
	}

}

class B implements Runnable{
	
	MyClass01 mc;
	
	B(MyClass01 mc){
		this.mc = mc;
	}
	
	@Override
	public void run() {
		if (Thread.currentThread().getName().equals("t1")) {
			mc.m1();
		}
		if (Thread.currentThread().getName().equals("t2")) {
			mc.m2();
		}
	}
	
}


class MyClass01{
	
	public synchronized void m1(){
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("m1....");
	}
	
	//m2方法不会等m1方法结束  ,t1和t2不共享一个mc
	public synchronized void m2(){
		System.out.println("m2......");
	}
	
	
}



类锁(只有一个,synchronized+静态方法)

因为有synchronized添加到静态方法上面的,线程执行到此方法会找类锁m2方法等m1方法结束之后才能执行,虽然t1与t2的mc对象不一样,但是m2方法还是会等m1的

(就好像两个人,分别去两个不同的茅坑上厕所,但是只有你手里有一瓢水可以冲,他不确定他上的时候有没有水冲,所以得等你上完,再拿水上)


/*
 * 类锁  类只有一个  所以是类级别的,只有一个
 * */
public class ThreadTest16 {

	public static void main(String[] args) throws Exception {
		MyClass03 mc1 = new MyClass03();
		MyClass03 mc2 = new MyClass03();
		
		Thread t1 = new Thread(new D(mc1));
		Thread t2 = new Thread(new D(mc2));
		
		t1.setName("t1");
		t2.setName("t2");
		
		t1.start();
		Thread.sleep(1000);
		t2.start();

	}

}

class D implements Runnable{
	MyClass03 mc;
	
	D(MyClass03 mc){
		this.mc = mc;
	}
	
	public void run(){
		if ("t1".equals(Thread.currentThread().getName())) {
			mc.m1();//用的还是类锁  和对象没有关系
		}
		if("t2".equals(Thread.currentThread().getName())){
			mc.m2();
		}
	}
	
}

class MyClass03{
	
	//synchronized  添加到静态方法上面的,线程执行到此方法会找类锁
	public synchronized static void m1(){
		
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("m1......");
	}
	
	//m2方法等m1方法结束之后才能执行,因为有synchronized
	//线程执行该代码需要类锁  但是类锁只有一个
	public synchronized static void m2(){
		System.out.println("m2......");
	}
	
}





Thread.setDaemon(true);

 *守护线程
 
  等其他用户线程全部结束后则守护线程退出
 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值