java之11天 多线程 (二)

卖票安全问题 

//线程出现安全问题啦 !!! 卖出了 0  -1 -2 号票了

class SaleTicket1 implements Runnable{
	private int ticks=100; 
	private long time=1000; //加上这个后 就让安全问题 跟明显了 
	public void run(){  //复写接口中的方法 ,不能抛异常 ,只能try
		while(true){
			if(ticks>0){
				try {
					if(time>0){
						Thread.currentThread().sleep(time);
						time=time-200;
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
			}
		}
	}
		
}


//使用  synchronized 同步代码块 来解决
class SaleTicket2 implements Runnable{
	private int ticks=100; 
	private long time=1000; //加上这个后 就让安全问题 跟明显了
	Object obj=new Object();
	
	public void run(){  //复写接口中的方法 ,不能抛异常 ,只能try
		while(true){
			synchronized(obj){ //同步代码块  obj :称为锁 
				if(ticks>0){
					try {
						if(time>0){
							Thread.currentThread().sleep(time);
							time=time-200;
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
				}
			}
		}
	}
		
}


//使用 synchronized 同步函数 来解决
class SaleTicket3 implements Runnable{
	private int ticks=100; 
	private long time=1000; //加上这个后 就让安全问题 跟明显了
	//Object obj=new Object();
	
	public void run(){  //复写接口中的方法 ,不能抛异常 ,只能try
		while(true){
			//synchronized(obj){ //同步代码块  obj :称为锁 
				this.show();
			//}
		}
	}
	
	//同步函数 来解决
	public synchronized void show(){
		if(ticks>0){
			try {
				if(time>0){
					Thread.currentThread().sleep(time);
					time=time-200;
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
		}
	}
		
}



*  同步函数 用的是那一个锁呢 .????(this 锁)
/**
 * 
 *  函数需要被对象调用, 那么函数都一个所属对象的引用,就是 this
 *  所以同步函数使用的锁是 this
 * 
 *  通过程序来进行验证 同步函数使用的是 this
 *
 *  使用两个程序来买票 
 * 一个线程在不同步代码快找那个
 * 一个线程在同步函数中
 * 都在执行买票动作.
 *
 */
class SaleTicket implements Runnable{
	private int ticks=1000; 
	private long time=10; //加上这个后 就让安全问题更明显了
	Object obj=new Object();
	boolean flag=true;
	public void run(){  //复写接口中的方法 ,不能抛异常 ,只能try
		if(flag){
			while(true){
				/**
				 * 发现 使用 obj 的时候 卖出的票 出现了  0  -1 -2  ,说明同步没有成功,  
				 * 找原因发现, 不满足线程同步第二个条件, 就是使用的不是同一个锁,
				 *  把 obj 换成 this 试试  发现 结果正确了 由此 
				 *  
				 */
				synchronized(this){  //obj -->this
					if(ticks>0){
						try {
							if(time>0){
								Thread.currentThread().sleep(time);
								///time=time-200;
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
					}
				}
			}
		}else
			while(true)
					this.show();
	}
	
	/*
	 * 同步函数 用的是那一个锁呢 .
	 * 
	 * 函数需要被对象调用, 那么函数都一个所属对象的引用,就是 this
	 * 所以同步函数使用的锁是 this
	 * 
	 */
	public synchronized void show(){
		if(ticks>0){
			try {
				if(time>0){
					Thread.currentThread().sleep(time);
					//time=time-200;
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
		}
	}
		
}



main Test
public class ThreadDemo1 {
	public static void main(String[] args) {
		SaleTicket t1=new SaleTicket();
		
		Thread th1=new Thread(t1);  //创建了一个线程 并将Runnable 子类对象给  Thread 构造函数
		Thread th2=new Thread(t1); 
		//Thread th3=new Thread(t1);  
		//Thread th4=new Thread(t1);  
		
		th1.start();
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		t1.flag=false;
		th2.start();  
		//th3.start();
		//th4.start();
		
		
//测试  同步函数使用的锁时候  ,只需要用 两个线程就可以了 其他的 4个 来测试 .
	}

}


静态同步函数 (Class 锁)

/**
* 如果同步函数被静态就是后,使用的锁是什么呢?
* 通过验证,发现 不在是 this ,因为静态中不可以定义 this
*
* 静态进内存是,内存中没有本类对象,但是一定有该类对应的字节码文件对象
* 类名.class  该对象的类型是Class 
*
* 通过下面的测试 发现 
* 静态的同步方法,使用的锁是该方法所在类的字节码文件对象, 类名 .calss
*
*/
class SaleTicket implements Runnable{
	private static int ticks=1000; 
	private static long time=10; //加上这个后 就让安全问题更明显了
	//Object obj=new Object();
	boolean flag=true;
	public void run(){  //复写接口中的方法 ,不能抛异常 ,只能try
		if(flag){
			while(true){
				synchronized(SaleTicket.class){  //obj(不安全卖出了 0 号票) -->this(不安全卖出了 0 号票)--->SaleTicket.calss (安全了 发现从此没有卖出 0号票了)
					if(ticks>0){
						try {
							if(time>0){
								Thread.currentThread().sleep(time);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
					}
				}
			}
		}else
			while(true)
					this.show();
	}
	
	//静态 同步方法
	public static synchronized void show(){
		if(ticks>0){
			try {
				if(time>0){
					Thread.currentThread().sleep(time);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
		}
	}
		
}

public class ClassLoaclDemo {
	public static void main(String[] args) {
		SaleTicket t1=new SaleTicket();
		
		Thread th1=new Thread(t1);  //创建了一个线程 并将Runnable 子类对象给  Thread 构造函数
		Thread th2=new Thread(t1); 
		
		th1.start();
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		t1.flag=false;
		th2.start();
		
	}

}


单例模式
/**
 * 单例模式 
 * 
 *  //饿汉式
 *  class Single{
 *    private static final Single s=new Single();
 *    private Single();
 *    public static Single getInstance(){
 *    	return s;
 *    }
 *  }
 *  
 *  
 *  //懒汉式
 *  class Single{
 *   private static Single s=null;
 *   private Single(){}
 *   public static Single getInstance(){
 *     if(s=null)
 *        s=new Single();
 *     return s;
 *   }
 *   
 *   
 *  
 *  }
 *  
 * 
 *
 */

//懒汉式 加入 同步 效率比较低效
class Single{
	private static Single s=null;
	private Single(){}
	//使用 同步函数
	public static synchronized Single getInstance1(){
		if(s==null)
			s=new Single();
	   return s;
	}
	
	//使用 同步代码快
	public static Single getInstance(){
		if(s==null){  //使用双重判断 增加  懒汉式 的效率
			synchronized(Single.class){
				if(s==null)
					s=new Single();
			}
		}
	   return s;
	}
	
}

public class SingleDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Single s =Single.getInstance();
	}

}



死锁1
/**
 * 死锁
 * 通常,是同步中嵌套同步,但是锁不同
 *
 */

class SaleTicket implements Runnable{
	private int ticks=1000; 
	private long time=10; 
	Object obj=new Object();
	boolean flag=true;
	public void run(){  
		if(flag){
			while(true){
				synchronized(obj){  //同步代码块 里面有同步 函数
					show();   //this
				}
			}
		}else
			while(true)
					this.show();  //this 
	}
	
	//同步函数里面有 同步代码块 
	public synchronized void show(){//使用的是 this 
		synchronized(obj){    //这里确使用的  obj
			if(ticks>0){
				try {
					if(time>0){
						//Thread.sleep(time);
						Thread.currentThread().sleep(time);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+".....sale...."+ticks--);
			}
		}
	}
		
}

public class DeadLocalDemo {

	public static void main(String[] args) {
		SaleTicket t1=new SaleTicket();
		
		Thread th1=new Thread(t1);  //创建了一个线程 并将Runnable 子类对象给  Thread 构造函数
		Thread th2=new Thread(t1); 
		//Thread th3=new Thread(t1);  
		//Thread th4=new Thread(t1);  
		
		th1.start();
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		t1.flag=false;
		th2.start();
		//th3.start();
		//th4.start();
	}

}


死锁2
**
 * 请写一个简单的死锁例子
 */
class Test implements Runnable{
	private boolean flag;
	Test(boolean flag){
		this.flag=flag;
	}
	
	public void run(){
		if(flag){
			synchronized (MyLock.locka) {
				System.out.println("if locka");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized (MyLock.lockb) {
					System.out.println("if lockb");
				}
			}
		}else{
			synchronized (MyLock.lockb) {
				System.out.println("else lockb");
				synchronized (MyLock.locka) {
					System.out.println("else locka");
				}
			}
		}
	}
	
	
}
class MyLock{
	static Object locka=new Object();
	static Object lockb=new Object();
	
}

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

}

你可能感兴趣的:(synchronized,线程安全,死锁,同步代码块,同步函数)