并发2-Synchronized

Synchronized的使用

  • 修饰静态方法

  

//修饰静态方法
	public static synchronized void print() {
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"runing");
	}

  

  • 修饰非静态方法

  

//修饰非静态方法
	public  synchronized void print1() {
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"runing");
	}

  

  • 修饰代码块
	//代码块的使用
	public void prnit2() {
		synchronized (this) {
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"runing");
		}
		
	}
	
	//代码块的使用
		public void prnit3() {
			synchronized (SynchroTest.class) {
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"runing");
			}
			
		}

 

疑问:修饰代码块的时候,Synchronized参数对象起到了什么作用?

答:当JVM是用ClassLoader加载字节码的时候,会在方法区创建一个对象,同时也会在堆去创建一个Class(注意是大写的)。使用Synchronized.xxx.class就是说明所有Class对应的对象都使用共同一个锁(比较抽象)。这个Class一定是一个final的类。

java中每一个对象都会有一个monitor对象(监视器)。它的作用就是给对象加锁用的。

某一线程战友这个对象的时候,先看monitor的计数器是不是为0,如果是0说明还没有线程占有,此时会将monitor的计数器+1.如果不为0,表示有其他线程占有这个对象,需要等待。当占有这个对象的线程释放这个对象的时候,那么此时会将这个对象的monitor-1(并不是monitor=0,而是-1)。类似于CPU中的cache line作用。

线程堆栈分析

public static void main(String[] args) throws InterruptedException {
		final SynchroTest tSynchroTest1 = new SynchroTest();
		for (int i = 10; i < 15; i++) {
			new Thread(tSynchroTest1::print1).start();
		}
	}

	// 修饰非静态方法
	public synchronized void print1() {
		try {
			TimeUnit.MINUTES.sleep(2);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "runing");
	}

  根据以上代码进行分析。

jconsole分析,可以看出当前拥有对象锁的Thread-3因为线程睡眠,所以状态为TIMED_WAITING(等待状态)。看Thread-2可以看出总阻止数为1,也就是block状态(上锁状态)。

 

猜你喜欢

转载自www.cnblogs.com/gnwzj/p/10554316.html