java个人学习笔记17(synchronized+同步函数+同步代码块+死锁)

1.同步函数:就是在函数上加上同步关键字(syschronized)进行修饰
   同步函数使用的锁即this,调用该函数的对象(下面例子中的b)
   同步有两种形式:
1)同步代码块

2)同步函数

/*
class Bank
{
	private int sum = 0;
	private Object obj = new Object();
	public void add(int money){
		synchronized(obj){
			sum = sum + money;
			System.out.println("sum"+sum);
		}//同步代码块
	}
}
*/
class Bank
{
	private int sum = 0;
	public synchronized void add(int money){
		sum = sum + money;
		System.out.println("sum"+sum);
	}//同步函数
}

class Customer implements Runnable
{
	private Bank b = new Bank();
	public void run(){
		for(int i = 0;i < 3;i++){
			b.add(100);
		}
	}
}
class BankDemo
{
	public static void main(String[] args) 
	{
		Customer c = new Customer();
		Thread t1 = new Thread(c);
		Thread t2 = new Thread(c);
		t1.start();
		t2.start();
	}
}

2.验证同步函数的锁是this

注意:静态(static)同步函数的锁是 类名.class

static方法随着类的加载,这时不一定有该类的对象,但一定有该类的字节码文件对象。

这个对象简单的表示为 类名.class

/**
验证同步函数的锁是this
思路:1)同步代码块使用明锁obj,同步函数使用this锁,如果执行同一个任务,
	  两线程将会出现不同步的现象。
	  2)将同步代码块的锁换成this,那么两线程将会同步
*/
class SaleTicket implements Runnable
{
	private int tickets = 100;
	Object obj = new Object();//synchronized(obj),相当于“锁”
	//flag用于进程0-1间的切换
	public boolean flag = true;
	public void run(){
		if(flag == true){
			while(true){
				synchronized(obj){//同步代码块
					if(tickets > 0){
						try{
							Thread.sleep(10);//线程停止执行10ms
						}catch(InterruptedException e){}
						System.out.println(Thread.currentThread().getName()+"..code.."+tickets--);
					}
				}
			}
		}
		else
			while(true)
				this.sale();
	}

	//同步函数
	public synchronized void sale(){
		if(tickets > 0){
			try{
				Thread.sleep(10);//线程停止执行10ms
			}catch(InterruptedException e){}
			System.out.println(Thread.currentThread().getName()+"..func.."+tickets--);
		}
	}
}

class TicketDemo 
{
	public static void main(String[] args) throws InterruptedException
	{
		SaleTicket t = new SaleTicket();
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		t1.start();
		//main线程停止执行10ms,执行t1线程
		Thread.sleep(10);
		//切换到t2线程
		t.flag = false;
		t2.start();
		

	}
}


3.单例模式的并发访问

/**
单例设计模式的并发访问
*/
/*
//恶汉式,不存在安全问题
class Single{
	private static final Single s = new Single();
	private Single(){}
	public static Single getInstance(){
		return s;
	}
}
*/
//懒汉式
class Single{
	private static Single s;
	private Single(){};
	public static Single getInstance(){
		//双if结构,提高了判断锁的效率
		if(s == null){
			//同步代码块
			synchronized(Single.class){
				if(s == null){
					s = new Single();
				}
			}
		}
		return s;
	}
}

class SingleWork implements Runnable{
	public void run (){
		while(true){
			Single.getInstance();
		}
	}
}
class SingleDemo{
	public static void main(String[] args) 
	{
		SingleWork w = new SingleWork();
		Thread t1 = new Thread(w);
		Thread t2 = new Thread(w);
		t1.start();
		t2.start();
		
	}
	
}
4.同步代码块和同步函数的区别

同步代码块可使用任意对象作为锁

同步函数只能使用this作为锁

5.死锁

/**
死锁:
场景一:
	同步嵌套,即两个以上的锁相互嵌套成环
*/

class Task implements Runnable{
	//flag用于两线程分别执行run中不同的代码块
	private boolean flag;
	Task(boolean flag){
		this.flag = flag;
	}
	public void run(){
		if(flag == true){
			while(true){
				synchronized(Mylock.locka){
					System.out.println("if...locka");				
					synchronized(Mylock.lockb){
						System.out.println("if...lockb");
					}
				}
			}
		}
		else{
			while(true){
				synchronized(Mylock.lockb){
					System.out.println("else...lockb");
					synchronized(Mylock.locka){
						System.out.println("else...locka");
					}
				}
			}
		}
	}
}
//定义两个锁locka和lockb
class Mylock{
	public static final Object locka = new Object();
	public static final Object lockb = new Object();
}

class DeadlockDemo{
	public static void main(String[] args){
		Thread t1 = new Thread(new Task(true));
		Thread t2 = new Thread(new Task(false));
		t1.start();
		t2.start();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值