`

Synchronized对象加锁防止并发

阅读更多
前言:处理简单的并发可以给对象加把锁,防止不同线程对同一资源同时进行操作,但是也需要谨慎使用"synchronized "关键字。
1、同步锁
package com.boonya.concurrent;

/**
 * Java同步锁
 * 
 * @author BOONYACHENGDU@GMAIL.COM 熟悉一下Synchronized的用法 写法
 */
public class SynchronizedInJava {

	/**
	 * 某线程执行method1()方法,则该对象将加锁。其它线程将无法执行该对象的所有synchronized块。
	 */
	public synchronized void method1() {
		// ....;
	}

	/**
	 * 同用法1, 但更能体现synchronized用法的本质。
	 */
	public void method2() {
		// 锁住本对象
		synchronized (this) {
			// ...;
		}
	}

	/**
	 * 测试方法3 执行method3(),会给对象a加锁,注意不是给SynchronizedInJava的对象加锁,也就是说 Test
	 * 对象的其它synchronized方法不会因为method3()而被锁。同步代码块执行完,则释放对a的锁。
	 */
	private String a = "test";

	public void method3() {
		// 锁住a对象
		synchronized (a) {
			// ...;
		}
	}

	public synchronized void t() {
		//这个同步代码块不会因为method3()而锁定.
		// ...; 
	}

	/**
	 * 为了锁住一个对象的代码块而不影响该对象其它 synchronized块的高性能写法
	 */
	private byte[] lock = new byte[0];

	public void method4() {
		synchronized (lock) {
			// ...;
		}
	}

	public synchronized void td() {
		// ...;
	}

	/**
	 * 静态方法锁
	 */
	public synchronized static void execute1() {
		// ...;
	}

	// 效果同上(静态方法锁)
	public static void execute2() {
		synchronized (SynchronizedInJava.class) {
			// ...;
		}
	}

}

2、死锁
多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性的访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。 由于这个原因,在使用“synchronized”关键词时,很容易出现两个线程互相等待对方做出某个动作的情形。
package com.boonya.concurrent;

/**
 * 模拟死锁出现的情景
 * 
 * @author BOONYACHENGDU@GMAIL.COM 假设先调用 method1()
 *         首先lock_1对象被锁住,lock_2被锁住,lock_1直到lock_2执行完成后方才解锁;
 *         在method1执行的间隙,method2()被调用,由于lock_1、lock_2被锁定,造成线程阻塞,产生死锁。
 */
public class SynchronizedDeadlocker {

	int field_1;
	private Object lock_1 = new int[1];

	int field_2;
	private Object lock_2 = new int[1];

	public void method1(int value) {
		synchronized (lock_1) {
			synchronized (lock_2) {
				field_1 = 0;
				field_2 = 0;
			}
		}
	}

	public void method2(int value) {
		synchronized (lock_2) {
			synchronized (lock_1) {
				field_1 = 0;
				field_2 = 0;
			}
		}
	}
}


注:在实际生产环境中还是要考虑是否会产生死锁,避免灾难的发生。
参考资源:http://dapple.iteye.com/blog/787563
分享到:
评论

相关推荐

    深入java并发编程,使用ReentrantLock和 Synchronized加锁

    在Java并发编程中,理解和熟练使用同步机制是至关重要的,这包括了`ReentrantLock`和`synchronized`关键字。这两个工具都是为了确保多线程环境中的数据一致性与安全性,防止出现竞态条件和死锁等问题。 `...

    java synchronized加载加锁-线程可重入详解及实例代码

    Java中的`synchronized`关键字是用于实现线程同步的关键机制,它的主要目的是确保多线程环境下的数据一致性,防止数据竞争。在本例中,我们关注的是`synchronized`的线程可重入特性。 线程可重入是指一个线程已经...

    Java并发编程系列- synchronized

    1. **修饰实例方法**:当`synchronized`应用于实例方法时,它会对当前实例加锁。这意味着,当一个线程正在执行这个实例的`synchronized`方法时,其他线程试图调用该实例的任何其他`synchronized`方法都会被阻塞,...

    synchronized的几种示例

    本文将深入探讨`synchronized`的几种使用示例,包括方法加锁、代码块加锁(针对`this`和对象)以及静态方法加锁。 1. **方法加锁** 当在实例方法前使用`synchronized`关键字时,它会锁定当前对象的监视器,只有...

    Java 多线程与并发(4-26)-关键字- synchronized详解.pdf

    加锁是指在访问共享资源时,先锁定资源,以防止其他线程访问该资源;释放锁是指在访问完毕资源时,释放锁,以便其他线程可以访问该资源。 synchronized 关键字的缺陷 synchronized 关键字虽然可以实现线程安全,...

    Synchronized关键字的用法

    `synchronized`是Java语言中的一个关键字,主要用于实现线程同步,防止多个线程同时访问共享资源而导致的数据不一致问题。通过`synchronized`关键字,开发者可以控制代码块或方法的并发访问,从而确保数据的一致性和...

    Java并发编程:Synchronized及其实现原理

    在这个例子中,`method1()`内部的同步代码块只对`lock`对象加锁,与其他使用相同锁的对象无关。 二、Synchronized实现原理 Synchronized在JVM层面上主要依赖于Monitor(监视器锁),这是由操作系统的底层互斥量...

    Synchronized与ThreadLocal

    - Synchronized 的性能开销较大,尤其是在高并发环境下,因为涉及锁的获取和释放。 - ThreadLocal 相对来说具有更好的性能,因为它避免了线程间的同步,减少了锁的开销。 #### 四、案例分析 假设有一个场景,...

    NSLock和@synchronized

    在这里,`self`是一个对象,`@synchronized`会为这个对象创建一个隐式的锁。当进入同步块时,会尝试获取锁,如果成功则执行代码,完成后自动解锁。`@synchronized`的加锁和解锁操作是原子性的,因此不会发生数据竞争...

    Synchronized_思维导图(全面).xmind.zip

    synchronized方法是通过在方法声明前加上synchronized关键字来实现的,而synchronized块则是在代码块前加上关键字,指定一个监视器对象,只有获取到该对象锁的线程才能执行该代码块。 在Java 6之后,synchronized...

    计算机加锁源码

    在系统相关类的编程中,加锁机制是一种控制并发访问和防止数据不一致性的关键技术。它允许程序员实现线程同步,确保在同一时刻只有一个线程能够访问特定的代码段或数据。 加锁的基本原理是通过一种同步机制来限制对...

    详解java中的synchronized关键字

    总之,`synchronized`关键字是Java中实现线程安全的关键手段之一,它通过锁机制保护共享资源,防止数据不一致和竞态条件。然而,在实际应用中,需要根据具体需求来权衡其性能和功能,有时可能需要结合使用其他并发...

    java多线程系列(二)对象变量并发访问.docx

    为了实现线程安全,通常会采用加锁机制,如synchronized关键字,来确保在任何时候只有一个线程可以访问特定的共享资源。当一个线程在执行涉及共享数据的操作时,其他试图访问该数据的线程会被阻塞,直到第一个线程...

    Java对象锁和类锁全面解析(多线程synchronize

    2. **修饰静态方法**:等同于对类的Class对象加锁,所有实例共享同一把锁。 3. **修饰代码块**:指定要锁定的对象,只对代码块进行锁定,提高了锁的粒度,降低了锁冲突的可能性。 在实际编程中,合理使用`...

    Synchronized与Lock

    使用Lock接口的一个关键点是,必须记得在finally块中释放锁,以防止异常导致锁无法释放,导致死锁。 总结来说,synchronized是Java中的基本同步机制,简单易用但功能有限。而Lock接口(如ReentrantLock)提供了更...

    java并发问题概述

    在Java中,使用synchronized关键字可以对一个对象加锁,使得其他线程无法访问该对象的synchronized块。有三种使用synchronized的方法: 1. 在方法声明中使用synchronized关键字,例如: ```java public ...

    Java多线程同步具体实例讲解.doc

    这里 `this` 指向当前对象,所以使用 `synchronized` 修饰方法相当于对当前对象加锁。 - **同步块 (Synchronized Block)**:用 `synchronized` 修饰的代码块,如 `synchronized(obj) {...}`,它指定了一把锁,即 `...

    Java多线程中使用synchronized说明

    当`synchronized`关键字用于实例方法时,它会对该实例对象加锁。这意味着当一个线程进入某个对象的`synchronized`方法后,其他试图进入该对象任何`synchronized`方法的线程都将被阻塞,直到第一个线程执行完毕释放...

    各大公司校招笔试面试多线程和并发历年真题总结

    在更高级的并发场景中,可以使用并发包中的锁对象,如ReentrantLock,它提供了更为灵活的锁定机制,包括尝试获取锁、中断线程等待、以及条件变量等高级功能。 对于并发编程的学习,除了掌握理论知识外,进行实践是...

Global site tag (gtag.js) - Google Analytics