`

synchronized 关键字

 
阅读更多

synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法或者其它synchronized方法的线程B(或者C D等),有的话要等正在使用synchronized方法的线程B(或者C D)运行完这个方法后再运行此线程A,没有的话,直接运行 它包括两种用法:synchronized 方法和 synchronized 块。

1. synchronized 方法:

  声明是为了定义变量的作用范围和作用域  通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:  public synchronized void accessVal(int newVal);  synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。  在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。  synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized 块。

2. synchronized 块:

  通过 synchronized关键字来声明synchronized 块。语法如下:  synchronized(syncObject) {  //允许访问控制的代码  }  synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。

编辑本段对synchronized(this)的一些理解

  一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。  二、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。  三、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的除synchronized(this)同步代码块以外的部分。  四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。  五、以上规则对其它对象锁同样适用

编辑本段synchronized的4种用法

  
1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前。即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入。 
例如: 
public synchronized void synMethod() { 
//方法体 

2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块。例如: 
public int synMethod(int a1){ 
synchronized(a1) { 
//一次只能有一个线程进入 


3.synchronized后面括号里是一对象,此时,线程获得的是对象锁。例如: 
public class MyThread implements Runnable { 
public static void main(String args[]) { 
MyThread mt = new MyThread(); 
Thread t1 = new Thread(mt, "t1"); 
Thread t2 = new Thread(mt, "t2"); 
Thread t3 = new Thread(mt, "t3"); 
Thread t4 = new Thread(mt, "t4"); 
Thread t5 = new Thread(mt, "t5"); 
Thread t6 = new Thread(mt, "t6"); 
t1.start(); 
t2.start(); 
t3.start(); 
t4.start(); 
t5.start(); 
t6.start(); 

public void run() { 
synchronized (this) { 
System.out.println(Thread.currentThread().getName()); 



对于3,如果线程进入,则得到对象锁,那么别的线程在该类所有对象上的任何操作都不能进行。在对象级使用锁通常是一种比较粗糙的方法。为什么要将整个对象都上锁,而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源?如果一个对象拥有多个资源,就不需要只为了让一个线程使用其中一部分资源,就将所有线程都锁在外面。由于每个对象都有锁,可以如下所示使用虚拟对象来上锁: 
class FineGrainLock { 
MyMemberClass x, y; 
Object xlock = new Object(), ylock = new Object(); 
public void foo() { 
synchronized(xlock) { 
//access x here 

//do something here - but don‘t use shared resources 
synchronized(ylock) { 
//access y here 


public void bar() { 
synchronized(this) { 
//access both x and y here 

//do something here - but don‘t use shared resources 


4.synchronized后面括号里是类。例如: 
class ArrayWithLockOrder{ 
private static long num_locks = 0; 
private long lock_order; 
private int[] arr; 
public ArrayWithLockOrder(int[] a) 

arr = a; 
synchronized(ArrayWithLockOrder.class) {//-----------------------------------------这里 
num_locks++; // 锁数加 1。 
lock_order = num_locks; // 为此对象实例设置唯一的 lock_order。 


public long lockOrder() 

return lock_order; 

public int[] array() 

return arr; 


class SomeClass implements Runnable 

public int sumArrays(ArrayWithLockOrder a1, 
ArrayWithLockOrder a2) 

int value = 0; 
ArrayWithLockOrder first = a1; // 保留数组引用的一个 
ArrayWithLockOrder last = a2; // 本地副本。 
int size = a1.array().length; 
if (size == a2.array().length) 

if (a1.lockOrder() > a2.lockOrder()) // 确定并设置对象的锁定 
{ // 顺序。 
first = a2; 
last = a1; 

synchronized(first) { // 按正确的顺序锁定对象。 
synchronized(last) { 
int[] arr1 = a1.array(); 
int[] arr2 = a2.array(); 
for (int i=0; i value += arr1[i] + arr2[i]; 



return value; 

public void run() { 
//... 


对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁。 
以上4种之间的关系: 
锁是和对象相关联的,每个对象有一把锁,为了执行synchronized语句,线程必须能够获得synchronized语句中表达式指定的对象的锁,一个对象只有一把锁,被一个线程获得之后它就不再拥有这把锁,线程在执行完synchronized语句后,将获得锁交还给对象。 
在方法前面加上synchronized修饰符即可以将一个方法声明为同步化方法。同步化方法在执行之前获得一个锁。如果这是一个类方法,那么获得的锁是和声明方法的类相关的Class类对象的锁。如果这是一个实例方法,那么此锁是this对象的锁。synchronzied块后面跟类的具体详细例子、public class DB2_JDBCFactory {private static DB2_JDBCFactory instance = null; public static final ThreadLocal threadLocal = new ThreadLocal(); private DB2_JDBCFactory() { 
} public static DB2_JDBCFactory getInstance() { 
if(instance == null) { 
synchronized(DB2_JDBCFactory.class) { //synchronized后面跟一个类 
instance = new DB2_JDBCFactory(); 


return instance; 
} public Connection getConnection_JNDI_localhost(){ 
Connection c = (Connection) threadLocal.get(); 
try { 
if (c == null || c.isClosed()) { 
InitialContext ctx = new InitialContext(); 
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/localhost"); 
c = ds.getConnection(); 
threadLocal.set(c); 

} catch (Exception ex) { 
System.err.println("getConnection_JNDI Initial failed. " + ex); 
return null; 

return c; 
}}外面的对象访问这个类的 需要通过调用它的getInstance()
分享到:
评论

相关推荐

    java多线程中synchronized关键字的用法

    java多线程中synchronized关键字的用法 解压密码 www.jiangyea.com

    java的线程同步机制synchronized关键字的理解_.docx

    Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...

    java同步synchronized关键字用法示例

    Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源时的同步机制。在Java中,当多个线程试图同时访问和修改同一块代码或数据时,可能会导致数据不一致的问题。为了解决这个问题,...

    深入理解Java中的synchronized关键字:同步机制与应用

    Java提供了多种机制来处理并发问题,其中synchronized关键字是最基本也是最常用的同步手段之一。本文将深入探讨synchronized关键字的工作原理、使用方式以及在实际编程中的应用。 synchronized关键字是Java中实现...

    实例解析Java中的synchronized关键字与线程平安问题_.docx

    Java 中的 synchronized 关键字与线程平安问题 在 Java 中,synchronized 关键字是一个非常重要的概念,它用于解决线程同步问题。但是,很多开发者对 synchronized 关键字的理解并不够深入,本文将通过实例解析 ...

    synchronized关键字的用法详解

    ### synchronized关键字的深入解析 #### 一、synchronized关键字的重要性 `synchronized`关键字在Java语言中扮演着极其重要的角色,它是实现线程安全的核心手段之一。通过`synchronized`关键字,开发人员可以在多...

    Java并发编程:Synchronized关键字深度解析

    本文深入探讨了Java中用于解决并发编程中线程安全问题的synchronized关键字。文章首先讨论了多线程编程中临界资源的概念,包括对象、变量、文件等,以及同步机制的必要性。重点解析了synchronized的工作原理,包括其...

    【Java并发编程】Synchronized关键字实现原理.doc

    Java 并发编程 Synchronized 关键字实现原理 Synchronized 关键字是 Java 并发编程中最基本的同步机制,它可以保证线程安全,包括原子性、可见性和有序性。Synchronized 关键字可以修饰方法或代码块,使得在同一...

    java基本教程之synchronized关键字java多

    一、synchronized关键字的作用与原理 `synchronized`关键字主要有两个作用:同步方法和同步块。它通过锁机制来实现线程同步,防止多个线程同时执行同一段代码,可能导致的数据不一致问题。 1. 同步方法:当在方法...

    Lock接口与synchronized关键字

    ### Lock接口与synchronized关键字详解 #### 一、概述 在Java并发编程中,Lock接口与synchronized关键字都是实现同步的重要工具。它们虽然都用于控制多线程对共享资源的访问,但在使用方式、功能特性及灵活性方面...

    Synchronized关键字的用法

    ### Synchronized关键字在Java中的应用 #### 概述 `synchronized`是Java语言中的一个关键字,主要用于实现线程同步,防止多个线程同时访问共享资源而导致的数据不一致问题。通过`synchronized`关键字,开发者可以...

    synchronized关键字的实质及用法

    《深入理解Java中的synchronized关键字》 在Java编程语言中,`synchronized`关键字是用于实现线程同步的重要工具,它的本质在于确保多线程环境下的数据一致性与安全性。通过`synchronized`,我们可以控制对共享资源...

    Java并发-Synchronized关键字.docx

    本文将探讨Synchronized关键字在解决并发控制中的作用及其使用方式。 首先,让我们回顾一下问题的背景:在给出的示例代码中,创建了10个线程,每个线程都对共享变量`count`进行10000000次的累加操作。理论上,最终...

    java synchronized关键字原理、自定义一把锁来实现同步等

    ### Java synchronized 关键字原理与自定义锁实现详解 #### 一、Java synchronized 关键字原理 `synchronized` 是 Java 中的关键字之一,用于实现线程间的同步控制,确保共享资源的安全访问。它主要应用于以下两种...

    java实现单例模式-懒汉模式(线程安全,使用synchronized关键字)

    线程安全,使用synchronized关键字

    5-4JVM内置锁synchronized关键字详解.mp4

    5-4JVM内置锁synchronized关键字详解.mp4

    Java中的同步机制:深入理解synchronized关键字

    synchronized关键字是Java中实现线程同步的基本工具,它通过锁定对象的monitor来控制对共享资源的并发访问。理解synchronized的工作原理和使用方式对于编写线程安全的Java程序至关重要。然而,由于其局限性,开发者...

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

    "Java 多线程与并发(4-26)-关键字- synchronized详解" Java 多线程与并发中的 synchronized 关键字是实现同步块的互斥访问和线程的阻塞及唤醒等工作的重要工具。下面将对 synchronized 关键字进行详细分析。 ...

    Java synchronized关键字使用方式及特性解析

    需要注意的是,synchronized关键字的使用需要遵守一定的原则,例如避免使用synchronized关键字在循环语句中,以免出现死锁等问题。此外,synchronized关键字也可以与其他线程同步工具结合使用,以实现更复杂的线程...

Global site tag (gtag.js) - Google Analytics