博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA并发---记录2
阅读量:4313 次
发布时间:2019-06-06

本文共 4977 字,大约阅读时间需要 16 分钟。

个人记录:

一、没有同步的情况

package com.shob.syn;public class Syn {	/**	 * synchronized是JAVA中解决并发问题的一种最常用的方法,也是最简单的方法。 作用有三个: 1、确保线程互斥的访问同步代码	 * 2、保证共享变量的修改能够及时可见 3、有效解决重排序问题 用法: 1、修改普通方法 2、修饰静态方法 3、修饰代码块	 */	private void desc() {	}	//没有同步的情况:	public void method1() {		System.out.println("Method 1 start");		try {			System.out.println("Method 1 execute");			Thread.sleep(3000);		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 1 end");	}	public void method2() {		System.out.println("Method 2 start");		try {			System.out.println("Method 2 execute");			Thread.sleep(1000);		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 2 end");	}	public static void main(String[] args) {		final Syn test = new Syn();		new Thread(new Runnable() {			@Override			public void run() {				test.method1();			}		}).start();		new Thread(new Runnable() {			@Override			public void run() {				test.method2();			}		}).start();	}}

  二、对普通方法同步

package com.shob.syn;public class SynO {	/**	 * 对普通方法同步:	 * 线程2需要等待线程1的method1执行完成才能开始执行method2方法。	 */		public synchronized void method1() {		System.out.println("Method 1 start");		try {			System.out.println("Method 1 execute");			Thread.sleep(3000);		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 1 end");	}	public synchronized void method2() {		System.out.println("Method 2 start");		try {			System.out.println("Method 2 execute");			Thread.sleep(1000);		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 2 end");	}		//由同一对象执行	public static void main(String[] args) {		final SynO test = new SynO();		new Thread(new Runnable() {			@Override			public void run() {				test.method1();			}		}).start();		new Thread(new Runnable() {			@Override			public void run() {				test.method2();			}		}).start();	}}

  三、静态方法(类)同步

package com.shob.syn;public class SynT {	/**	 * 静态方法(类)同步	 * 对静态方法的同步本质上是对类的同步(静态方法本质上是属于类的方法,而不是对象上的方法),所以即使test和test2属于不同的对象,	 * 但是它们都属于SynchronizedTest类的实例,所以也只能顺序的执行method1和method2,不能并发执行。	 */	public static synchronized void method1() {		System.out.println("Method 1 start");		try {			System.out.println("Method 1 execute");			Thread.sleep(3000);		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 1 end");	}	public static synchronized void method2() {		System.out.println("Method 2 start");		try {			System.out.println("Method 2 execute");			Thread.sleep(1000);		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 2 end");	}	//由不同对象执行,但是方法为静态方法属于类,而2个对象都是这个类的实例,相对静态方法需同步进行	public static void main(String[] args) {		final SynT test = new SynT();		final SynT test2 = new SynT();		new Thread(new Runnable() {			@Override			public void run() {				test.method1();			}		}).start();		new Thread(new Runnable() {			@Override			public void run() {				test2.method2();			}		}).start();	}}

  四、代码块同步

package com.shob.syn;public class SynS {		/**	 * 代码块同步	 * 虽然线程1和线程2都进入了对应的方法开始执行,但是线程2在进入同步块之前,需要等待线程1中同步块执行完成。	 */		public void method1() {		System.out.println("Method 1 start");		try {			synchronized (this) {				System.out.println("Method 1 execute");				Thread.sleep(3000);			}		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 1 end");	}	public void method2() {		System.out.println("Method 2 start");		try {			synchronized (this) {				System.out.println("Method 2 execute");				Thread.sleep(1000);			}		} catch (InterruptedException e) {			e.printStackTrace();		}		System.out.println("Method 2 end");	}	public static void main(String[] args) {		final SynS test = new SynS();		new Thread(new Runnable() {			@Override			public void run() {				test.method1();			}		}).start();		new Thread(new Runnable() {			@Override			public void run() {				test.method2();			}		}).start();	}}

  总:

package com.shob.syn;public class SynDemo {	/**	 * 	 * monitorenter:	 * 每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:		1、如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。		2、如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.		3.如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。	 */	private void method(){		//monitorenter 		synchronized (this) {						System.out.println("Method 1 start");		}		//monitorexit	}		/**	 * monitorexit	 * 	 * 执行monitorexit的线程必须是objectref所对应的monitor的所有者。		指令执行时,monitor的进入数减1,如果减1后进入数为0,那线程退出monitor,		不再是这个monitor的所有者。其他被这个monitor阻塞的线程可以尝试去获取这个 monitor 的所有权。 	 */			/**	 * 方法的同步方法的同步并没有通过指令monitorenter和monitorexit来完成(理论上其实也可以通过这两条指令来实现),	 *  不过相对于普通方法,其常量池中多了ACC_SYNCHRONIZED标示符。	 * JVM就是根据该标示符来实现方法的同步的:当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,	 * 如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。	 * 在方法执行期间,其他任何线程都无法再获得同一个monitor对象。 其实本质上没有区别,只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成。	 */	private synchronized void me(){		System.out.println("Method 2 start");	}}

  

转载于:https://www.cnblogs.com/binbang/p/6370712.html

你可能感兴趣的文章
Python(4)_Python中的数据类型
查看>>
HTTP 响应头信息
查看>>
cocos2dx中的层CCLayer
查看>>
Windows XP硬盘安装Ubuntu 12.04双系统图文详解
查看>>
【资料】哈代&拉马努金相关,悼文,哈佛演讲,及各种杂七杂八资料整理
查看>>
Use weechat (IRC client) on OS X. MacBook Pro
查看>>
Luogu P3616 富金森林公园
查看>>
[Nowcoder] 六一儿童节(拼多多)
查看>>
centos6.7用yum安装redis解决办法及IP限制配置
查看>>
用DataReader 分页与几种传统的分页方法的比较
查看>>
看起来像是PS的照片,实际上却令人难以置信!
查看>>
随笔一则
查看>>
WEB 小案例 -- 网上书城(一)
查看>>
加入博客园八个月了
查看>>
怎样实现前端裁剪上传图片功能
查看>>
python flask 如何修改默认端口号
查看>>
Map<String,Object> map=new HashMap<String,Object>详解
查看>>
实现tap的多种方式
查看>>
UVA - 10494 If We Were a Child Again
查看>>
html5 canvas 渲染像素混合模式
查看>>