Java中synchronized使用的一点见解

原创 2016年08月29日 18:33:52

第一篇文章,我先简单介绍下我的情况。普通一本院校的软件工程专业本科学生。现阶段大四,在北京中软国际进行实训。

培训的方向是java 企业级开发。在中软已经培训了一个月多。培训是从零开始学起。所以又从最基本的语法开始学习。第二次学习总是感受颇深。有些地方也有了新的感悟。很多以前不接触的语法或知识也逐渐掌握。

第一次接触java中的synchronize关键字应该是在操作系统课程的实验课上。要求做哲学家进餐问题。使用锁机制,某一线程代码段的原子性。当时使用了一个单独的类,在类中定义了一个静态Object变量当作锁。而所有线程中synchronize代码块均对该object变量加锁,以实现其 查看标识变量并更改标识变量 的原子操作。此处不再详述。

最近重学线程一块。无论是老师讲课,还是网上,总是要求区分synchronize锁方法,锁this,锁对象甚至锁class的区别。而在我的理解,锁方法等同与锁this。

锁方法:

public synchronized void method()
{
  //do some thing
}

public void method() {
		synchronized (this) {
			// do some thing
		}
	}


具有相同的使用效果。即当两个线程同时访问同一个对象的同步代码(锁this)块或同步方法(锁方法),只有一个线程可以得到执行。另一个线程受到阻塞。当两线程访问同一个类的不同对象时,不会产生阻塞。

再说一下锁对象,即锁某个object。

public class MyThread implements Runnable {
	public static void main(String[] args) {
		MyThread m1 = new MyThread();
		MyThread m2 = new MyThread();
		Thread t1 = new Thread(m1);
		Thread t2 = new Thread(m2);
		t1.start(); t2.start();
	}

	public void run() {
		synchronized (Locker.num) {
			for (int i = 0; i < 5; i++)
				System.out.println(Thread.currentThread().getName());
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
public class Locker {
	public static Integer num = 0;
}


相信学习过java的人也一定能理解。这个代码产生的结果将是其中一个线程将同步块执行完后。另一个线程才可能进入同步块执行。即另一个线程被阻塞。

运行结果如下

Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1


然后这时候,老师或者网上就总会对你说,他们都对同一个对象上了锁。把这个对象锁住了。所以别的线程不能再对其进行加锁,修改等操作。

但我理解的是,对象是一个锁。而被加锁的是{}中的代码。若是同一个对象,那就是同一把锁。既然这把锁已经被别的线程用了且锁住了。所以这个线程就无法获得这个锁,进而进入了等待状态,直到占用了锁的线程将锁释放。

在使用这个对象锁的时候。并不影响其他线程对这个对象进行读或修改的操作。这也就是所谓的加锁的是{}代码块,而非()中的对象。

public class Runnable1 implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			//R1对Locker.num对象进行修改但不上锁
			System.out.println("R1:" + ++Locker.num);
			try {
				Thread.sleep(20);
			} catch (Exception e) {
			}
		}
	}
}
public class Runnable2 implements Runnable {
	@Override
	public void run() {
		// R2对Locker.num对象进行上锁
		synchronized (Locker.num) {
			for (int i = 0; i < 10; i++) {
				System.out.println("R2:" + --Locker.num);
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
public class test {
	public static void main(String[] args) {
		Family family = new Family();
		family.money = 100.0;
		Runnable1 r1 = new Runnable1();
		Runnable2 r2 = new Runnable2();
		Thread t1 = new Thread(r1);
		Thread t2 = new Thread(r2);
		t1.start();
		t2.start();
	}
}
R2:-1
R1:1
R2:0
R1:2
R1:1
R2:-1
R2:0
R1:1
R2:0
R1:2
R2:-1
R1:1
R1:2
R2:0
R1:1
R2:-1
R1:0
R2:-1
R1:0
R2:-2

结果如上图。即R2对Lock.num的加锁并没有影响到R1对Lock.num的读写。

所以无论是锁this,锁object,锁Object.class(其本质也是一个静态对象) 要想知道其是否会造成阻塞,只可单线程进入代码块,而非交叉运行,只需分辨不同线程中同步代码块()中的对象是否为同一个即可。若为同一个。则可以实现阻塞,否则互不影响。

一句话总结,不同线程中,具有相同对象锁的代码块中语句不可交叉执行,会发生阻塞。





版权声明:本文为博主原创文章,未经博主允许不得转载。

Java中Synchronized的用法 (写的非常好,非常清晰)

原文:http://blog.csdn.net/luoweifu/article/details/46613015 作者:luoweifu 转载请标名出处 《编程思想之多线程与多进程(...
  • lostinai
  • lostinai
  • 2015年12月11日 20:50
  • 525

java synchronized的作用

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。      一、当两个并发线程访问同一个对象object中的这个synchroni...
  • crazy_kid_hnf
  • crazy_kid_hnf
  • 2017年03月15日 19:44
  • 785

Java多线程中 synchronized和Lock的区别

在上一节中, 我们已经了解了Java多线程编程中常用的关键字synchronized,以及与之相关的对象锁机制。这一节中,让我们一起来认识JDK 5中新引入的并发框架中的锁机制。 我想很多购买...
  • lingzhm
  • lingzhm
  • 2015年04月08日 21:28
  • 11268

怎样在静态方法中使用 synchronized

synchronized 的实现方式synchronized 的类型可以分为两种: synchronized method synchronized block 两者的实现方式是不一样的,jvm 规范...
  • FeeLang
  • FeeLang
  • 2015年11月09日 17:53
  • 4566

Java中Synchronized和Lock的使用和区别

转载自:http://blog.csdn.net/imzoer/article/details/9457639  Lock的锁定是通过代码实现的,而 synchronized 是在 JVM 层面...
  • zgrjkflmkyc
  • zgrjkflmkyc
  • 2016年03月02日 11:43
  • 3983

synchronized java的见解-)

打个比方:一个object就像一个大房子,大门永远打开。房子里有很多房间(也就是方法)。这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法)。房门口放着一把钥匙(key),这把...
  • sun305355024sun
  • sun305355024sun
  • 2009年11月17日 13:31
  • 407

Java多线程之~~~synchronized添加参数来实现独立的代码片段

有时候我们并不想在整个方法前面加上synchronized这个关键字,这样会使整个方法调用变的缓慢,我们只在关键 代码的地方增加这个synchronized这个关键字,然后这样就能加快方法或者代码的...
  • a352193394
  • a352193394
  • 2014年09月18日 22:48
  • 2996

synchronized java的见解

打个比方:一个object就像一个大房子,大门永远打开。房子里有很多房间(也就是方法)。这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法)。房门口放着一把钥匙(key),这把...
  • Jerry_Ran
  • Jerry_Ran
  • 2009年04月25日 10:32
  • 1050

java中几种synchronized用法总结

文章为自己测试后所写,有说得不对的地方希望看到的大神能够指出来让我得以改正,以免误导其他同行 synchronized方法,synchronized静态方法,synchronized(this),sy...
  • apeng_1102
  • apeng_1102
  • 2016年09月28日 09:31
  • 493

java多线程(五)synchronized关键字修饰代码块

在上一篇博客中我们介绍了
  • xingjiarong
  • xingjiarong
  • 2015年08月26日 09:11
  • 3566
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java中synchronized使用的一点见解
举报原因:
原因补充:

(最多只允许输入30个字)