Java 的synchronized 的复习 一

0:只要涉及到同时执行的那么就要就是多线程的,例如四个窗口同时卖票
1:实现多线程的方法有两种一个中是extends Thread,第二种是implement Runnable
如果解释的话就是:
第一种方式,线程任务和线程是绑定在一起的,创建了四个线程就创建了4份资源
第二种方式,线程任务和线程对象进行了分离,只需要创建一个任务对象(只有一个份资源),分别让四个线程去执行。

//第一种方法如下:每个窗口都有50张票
class Ticket1 extends Thread{
    int num=50;
    public void run(){
        while(true){
            if (num>0)
                System.out.println(Thread.currentThread().getName()+" sale "+num--);
        }
    }
}


Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
t1.start();
t2.start();


//第二种方法如下:几个窗口一共是50张票
class Ticket implements Runnable{
    int num=50;
    public void run(){
        while(true){
            if (num>0)
                System.out.println(Thread.currentThread().getName()+" sale "+num--);
        }
    }
}

//注意这里只有一个Ticket的对象,然后创建Thread的时候都是用的这个Ticket,不管是多少个窗口

Ticket ticket = new Ticket();
Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
t1.start();
t2.start();


2: 如果一起执行的里面只有一句话那么就没有同步的问题,

为了模仿同步问题,我们在
if (num>0)
                System.out.println(Thread.currentThread().getName()+" sale "+num--);
//下面继续执行:
if(num>0){
				System.out.print("  **********"+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.println(""+num);
				}

这样就会发现,但一个进行进行到一般的时候,例如在输入的时候,cpu 被其他的进程抢去了,然后才又回来执行


为了解决这种同步的问题,引入synchronized的,同步,
synchronized 的方法里面的东西,要执行必须全部执行完了,就和数据库事务有点像,或者说有点向上厕所,这个人上完了,别人才能上,总不能别人上一半的呢,你抢先去了把。synchronized 可以用来修饰方法,该方法的锁其实就是this,如果是静态的方法,那么锁就是类的class

所以现在其实就是将刚才要输出的东西使用这个synchronized(obj)来括一下,

class Ticket implements Runnable{
    int num=50;
	Object obj = new Object();
    public void run(){
        while(true){
			synchronized(obj){
				if (num>0)
					System.out.print(Thread.currentThread().getName()+" sale "+num--+"$$$$$$$$$$$");
				if(num>0){
				System.out.print("  **********"+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.print(""+num);
				System.out.println(""+num);
				}
			}
        }
    }
}


一个实例:一个银行可以存钱,两个人同时存钱,每个人存3次,每次存100
public class SaveMoney{
	public static void main(String[] args){
		Person person = new Person();
		Thread t1 = new Thread(person);
		Thread t2 = new Thread(person);
		Thread t3 = new Thread(person);
		
		t1.start();
		t2.start();
		t3.start();
	}
}


class Person implements Runnable{
	
	Bank bank = new Bank();
	int times = 3;
	public void run(){
		//存钱100一次,一共3次
		for(int i=0;i<3;i++)
		bank.add(100);
	}
}


class Bank{
		int sum = 12345;
		public synchronized void add(int addedNumber){
			
			System.out.print(Thread.currentThread().getName()+" 存之前的余额为"+sum);
			sum = sum+addedNumber;
			System.out.println("  当前的余额为"+sum);
		}
}



3:synchronized修饰的函数为同步函数,同步函数的同步锁是什么?是this,
但是如果是静态的同步函数,那么同步锁就是该类的class

class Ticket implements Runnable{
	static int num = 50;
	boolean flag = true;
	public void run(){
		if(flag==true){
			while(true){
				synchronized(Ticket.class){
					try{
						Thread.sleep(20);
					}catch(Exception e){
						//
					}
					if(num>0){
						System.out.print(Thread.currentThread().getName()+" sale "+num--);
					}
					if(num>0){
						System.out.print("  **********"+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.println(""+num);
					}
				}
			}
		}else{
			while(true){
				fun();
			}
		}
	}
	
	public synchronized static void fun(){
			
					try{
						Thread.sleep(20);
					}catch(Exception e){
						//
					}
					if(num>0){
						System.out.print(Thread.currentThread().getName()+" sale "+num--);
					}
					if(num>0){
						System.out.print("  -----------------------------------------"+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.print(""+num);
						System.out.println(""+num);
					}
	}
}












public class SaleTicket{
	public static void main(String[] args){
		Ticket t = new Ticket();
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		t1.start();
		try{Thread.sleep(20);}catch(Exception e){}
		t.flag=false;
		t2.start();
	}
}


4:死锁的发生:

/**模拟死锁的情况,
A要上楼,B要下楼,A在1层,B在4层,2层和3层有锁
A上楼的顺序是要2楼的钥匙,然后是3楼的,B下楼是先3楼,然后2楼。
顺利的情况是A 拿了2楼的钥匙,然后拿了三楼的钥匙,然后B 开始下楼哪了3楼的钥匙,然后是2楼的钥匙
所以就会出现两个人,A有了2楼的钥匙,但是要3楼的钥匙,B有了3楼的钥匙,但是要2楼的钥匙


*/
public class DeadLock{
	public static void main(String[] args){
		Test test = new Test();
		Thread t1 = new Thread(test);
		Thread t2 = new Thread(test);
		test.flag = 0;
		t1.start();
		//让主线程睡一会儿,那么就会执行上面的start的方法了,不然不执行的
		try{Thread.sleep(500);}catch(Exception e){}
		test.flag=1;
		t2.start();
		
	}
}




class Test implements Runnable{
	int flag;
	Object lock1 = new Object();
	Object lock2 = new Object();
	public void run(){
		
		if(flag==0){
			while(true){
				synchronized(lock1){
					try{
						Thread.sleep(50);
					}catch(Exception e){
						//
					}
					System.out.println("Flag = 1 已经有了lock1了,现在要lock2");
					synchronized(lock2){
						System.out.println("Flag = 1 获取了lock2");
					}
				}
			}
		}else{
			while(true){
				synchronized(lock2){
					try{
						Thread.sleep(50);
					}catch(Exception e){
						//
					}
					System.out.println("Flag = 2 已经有了lock2了,现在要lock1");
					synchronized(lock1){
						System.out.println("Flag = 1 获取了lock1");
					}
				}
			}
		}
	}
}


5:单例模式里面的并发的安全问题,
懒汉式中有:
public class SingleTest{
	public static void main(String[] args){
		Test test = new Test();
		Thread t1 = new Thread(test);
		Thread t2 = new Thread(test);
		Thread t3 = new Thread(test);
		Thread t4 = new Thread(test);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}


class Test implements Runnable{
	public void  run(){
		Single single = Single.getInstance();
		System.out.println(""+single.toString());
	}
}


class Single{
	private static Single single;
	private Single(){}
	public synchronized static Single getInstance(){
		if(single==null){
			single= new Single();
			return single;
		}else 
			return single;
	}
	
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值