synchronized 解析使用

java锁分为对象锁,类锁,

synchronized就是熟知的代码同步块。

加锁一个方法块,根据锁的机制上锁的只是这个对象,

package hw.lock;

/**
 * 
 * 
 * @author huangwei
 *	2017 10 20 
 */
public class Producer extends Thread{
	  int num=1;
	public synchronized int count() {
		
			while(num<10) {
			System.out.println(Thread.currentThread() +"   "+num++);//输出当前线程
			}
			
			
			try {
			Thread.sleep(500);
			}catch (Exception e) {
				// TODO: handle exception
			}
		
		return num;
		
	}
	
	public void run() {
		count();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Producer aProducer=new Producer();
		Producer bProducer=new Producer();
		aProducer.start();
		bProducer.start();
	}

}

输出为这样

Thread[Thread-1,5,main]   1
Thread[Thread-0,5,main]   1
Thread[Thread-0,5,main]   2
Thread[Thread-0,5,main]   3
Thread[Thread-0,5,main]   4
Thread[Thread-0,5,main]   5
Thread[Thread-0,5,main]   6
Thread[Thread-0,5,main]   7
Thread[Thread-0,5,main]   8
Thread[Thread-0,5,main]   9
Thread[Thread-1,5,main]   2
Thread[Thread-1,5,main]   3
Thread[Thread-1,5,main]   4
Thread[Thread-1,5,main]   5
Thread[Thread-1,5,main]   6
Thread[Thread-1,5,main]   7
Thread[Thread-1,5,main]   8
Thread[Thread-1,5,main]   9


说明如果只是对方法上锁的话,那么实际上会对当前的对象上锁,而我们实现了两个对象,所以并没有实现同步。


package hw.lock;

/**
 * 
 * 
 * @author huangwei
 *	2017 10 20 
 */
public class Producer extends Thread{
	  int num=1;
	public  int count() {
		synchronized (this) {
			while(num<10) {
			System.out.println(Thread.currentThread() +"   "+num++);//输出当前线程
			}
			
			
			try {
			Thread.sleep(500);
			}catch (Exception e) {
				// TODO: handle exception
			}
		}
		
		return num;
		
	}
	
	public void run() {
		count();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Producer aProducer=new Producer();
		Producer bProducer=new Producer();
		aProducer.start();
		bProducer.start();
	}

}

对当前对象进行上锁  输出结果依旧为没有上锁的样子

Thread[Thread-0,5,main]   1
Thread[Thread-1,5,main]   1
Thread[Thread-0,5,main]   2
Thread[Thread-1,5,main]   2
Thread[Thread-0,5,main]   3
Thread[Thread-0,5,main]   4
Thread[Thread-0,5,main]   5
Thread[Thread-0,5,main]   6
Thread[Thread-0,5,main]   7
Thread[Thread-0,5,main]   8
Thread[Thread-0,5,main]   9
Thread[Thread-1,5,main]   3
Thread[Thread-1,5,main]   4
Thread[Thread-1,5,main]   5
Thread[Thread-1,5,main]   6
Thread[Thread-1,5,main]   7
Thread[Thread-1,5,main]   8
Thread[Thread-1,5,main]   9

那对于两个不同的线程对象 我们要上锁的其实就是公有的属性,或者说就是静态属性。

package hw.lock;

/**
 * 
 * 
 * @author huangwei
 *	2017 10 20 
 */
public class Producer extends Thread{
	 static int num=1;
	public  int count() {
		synchronized (Producer.class) {
			while(num<10) {
			System.out.println(Thread.currentThread() +"   "+num++);//输出当前线程
			}
			
			
			try {
			Thread.sleep(500);
			}catch (Exception e) {
				// TODO: handle exception
			}
		}
		
		return num;
		
	}
	
	public void run() {
		count();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Producer aProducer=new Producer();
		Producer bProducer=new Producer();
		aProducer.start();
		bProducer.start();
	}

}


Thread[Thread-1,5,main]   1
Thread[Thread-1,5,main]   2
Thread[Thread-1,5,main]   3
Thread[Thread-1,5,main]   4
Thread[Thread-1,5,main]   5
Thread[Thread-1,5,main]   6
Thread[Thread-1,5,main]   7
Thread[Thread-1,5,main]   8
Thread[Thread-1,5,main]   9

如果是两个对象操作静态变量,对XX.class进行上锁就可以实现,对类上锁同步静态变量方法以及常量。


对于静态方法的synchronized就相当于给这个方法所在的这个内存块添加了一个监视器,


在类加载的时候,类的基本信息和一些常量和今天变量都保存在jvm内存的方法区,


对synchronized(XX.class)  就等于对这个类的所有信息加上 监视器,一个线程进行访问计数+1,释放-1,不为0就一直阻塞其他线程访问。


而类初始化的实例对象则放在了jvm内存的堆区

而对实例对象的上锁就相当于监视这个实例对象,而不同的对象在不同块  并不能实现同步。



对于同一个对象实例

未上锁时

package hw.lock;

/**
 * 
 * 
 * @author huangwei
 *	2017 10 20 
 */
public class Producer {
	 int num=1;
	public  int count() {
		
			while(num<10) {
			System.out.println(Thread.currentThread().getName() +"   "+num++);//输出当前线程
			}
			
			
			try {
			Thread.sleep(1000);
			}catch (Exception e) {
				// TODO: handle exception
			}
		
	
		return num;
		
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		final Producer aProducer=new Producer();
		//Producer bProducer=new Producer();
		Thread test1=new Thread(new Runnable() {
			
			@Override
			public void run() {
				aProducer.count();
				
			}
		});
		Thread test2=new Thread(new Runnable() {
			
			@Override
			public void run() {
				aProducer.count();
				
			}
		});
		test1.start();
		
		test2.start();
		//bProducer.start();
	}

}


Thread-0   1
Thread-1   1
Thread-0   2
Thread-1   3
Thread-0   4
Thread-1   5
Thread-0   6
Thread-1   7
Thread-0   8
Thread-1   9

对其当前对象上锁
package hw.lock;

/**
 * 
 * 
 * @author huangwei
 *	2017 10 20 
 */
public class Producer {
	 int num=1;
	public  int count() {
		synchronized (this) {		
			while(num<10) {
			System.out.println(Thread.currentThread().getName() +"   "+num++);//输出当前线程
			}
			
			
			try {
			Thread.sleep(1000);
			}catch (Exception e) {
				// TODO: handle exception
			}
		
		}
		return num;
		
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		final Producer aProducer=new Producer();
		//Producer bProducer=new Producer();
		Thread test1=new Thread(new Runnable() {
			
			@Override
			public void run() {
				aProducer.count();
				
			}
		});
		Thread test2=new Thread(new Runnable() {
			
			@Override
			public void run() {
				aProducer.count();
				
			}
		});
		test1.start();
		
		test2.start();
		//bProducer.start();
	}

}

Thread-0   1
Thread-0   2
Thread-0   3
Thread-0   4
Thread-0   5
Thread-0   6
Thread-0   7
Thread-0   8
Thread-0   9

由于num一直由第一个线程执行没有释放,所以第二个线程由于大于10直接结束。

直观一点 

num声明在方法内

package hw.lock;

/**
 * 
 * 
 * @author huangwei
 *	2017 10 20 
 */
public class Producer {
	
	public  int count() {
		 int num=1;
		synchronized (this) {		
			while(num<10) {
			System.out.println(Thread.currentThread().getName() +"   "+num++);//输出当前线程
			}
			
			
			try {
			Thread.sleep(1000);
			}catch (Exception e) {
				// TODO: handle exception
			}
		
		}
		return num;
		
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		 final Producer aProducer=new Producer();
		//Producer bProducer=new Producer();
		Thread test1=new Thread(new Runnable() {
			
			@Override
			public void run() {
				aProducer.count();
				
			}
		},"test1");
		Thread test2=new Thread(new Runnable() {
			
			@Override
			public void run() {
				aProducer.count();
				
			}
		},"test2");
		test1.start();
		
		test2.start();
		//bProducer.start();
	}

}


输出就为这样

test2   1
test2   2
test2   3
test2   4
test2   5
test2   6
test2   7
test2   8
test2   9
test1   1
test1   2
test1   3
test1   4
test1   5
test1   6
test1   7
test1   8
test1   9


简单的生产者消费者模型

package hw.lock;

/**
 * 
 * 
 * @author huangwei
 *	2017 10 20 
 */
public class Producer {
	int pnum=0;
	public  int count() {
		 int num=1;
		synchronized (this) {		
			while(num<10) {
			System.out.println(Thread.currentThread().getName() +"   "+num++);//输出当前线程
			}
			
			
			try {
			Thread.sleep(5000);
			}catch (Exception e) {
				// TODO: handle exception
			}
		
		}
		return num;
		
	}

	
	public void produce() {//生产者
		synchronized (this) {
			try {
			if(pnum>10) {
				this.wait();//数量上限等待
			}
			this.notify();//唤醒进程
			pnum++;
			System.out.println("生产者生产:1,还剩下:"+this.pnum);
			
				Thread.sleep(1000);
			}catch (Exception e) {
				// TODO: handle exception
			}
		}
		
		
	}
	
	public void customer() {//消费者
		synchronized (this) {
			try {
			if(pnum>0) {
				this.notify();//可以取  唤醒
				pnum--;
				System.out.println("消费者消费:1,还剩下:"+this.pnum);
				}else{
					System.out.println("消费者消费:0,储量不足");
					this.wait();//否则等待
				}
			
				Thread.sleep(1000);
			}catch (Exception e) {
				// TODO: handle exception
			}
		
		}
		
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		 final Producer aProducer=new Producer();
		//Producer bProducer=new Producer();
		Thread test1=new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true) {
				aProducer.produce();
				}
			}
		},"test1");
		Thread test2=new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true) {
				aProducer.customer();
				}
			}
		},"test2");
		test1.start();
		
		test2.start();
		
		//bProducer.start();
	}

}

生产者生产:1,还剩下:1
消费者消费:1,还剩下:0
消费者消费:0,储量不足
生产者生产:1,还剩下:1
生产者生产:1,还剩下:2
生产者生产:1,还剩下:3
生产者生产:1,还剩下:4
消费者消费:1,还剩下:3
生产者生产:1,还剩下:4
生产者生产:1,还剩下:5
生产者生产:1,还剩下:6
消费者消费:1,还剩下:5
消费者消费:1,还剩下:4
消费者消费:1,还剩下:3
生产者生产:1,还剩下:4
生产者生产:1,还剩下:5
生产者生产:1,还剩下:6
生产者生产:1,还剩下:7



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值