Java中使用synchronized关键字来加锁达到同步的目的,synchronized可以在作用在方法上,也可以作用在代码块上。
Java中的每一个对象都可以作为锁,但是基本数量类型不行,如int、float。
synchronized同步非静态方法
非静态同步方法,锁是当前对象实例,如下代码Info类中set()和get()方法都加上synchronized关键字同步,说明Info对象同一实例在同一时刻只能访问set()或get()方法:
public class Info { private String country; private String city; public synchronized void set(String country, String city) { System.out.println("进入设置方法..."); this.country = country; try { Thread.sleep(30000); } catch (InterruptedException e) { e.printStackTrace(); } this.city = city; System.out.println("完成设置..."); } public synchronized void get() { System.out.println("进入读取方法..."); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("country:" + this.country + "->city:" + this.city); } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
synchronized同步静态方法
同步静态方法,锁是当前类的Class对象。如Singleton单例模式在多线程下是不安全的,可以加synchronized关键字来同步,如下代码(此方法只为演示,在大多数情况下不需要同步,此方法性能不好):
public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
如下面测试代码,由于静态方法的锁有当前类的,所以每一个getInstance()方法都是同步的,所以性能不高:
/** * Huisou.com Inc. * Copyright (c) 2011-2012 All Rights Reserved. */ package thread; import java.util.Date; /** * @description * * @author chenzehe * @email hljuczh@163.com * @create 2012-12-4 下午05:33:21 */ public class Singleton { private static Singleton instance = null; private Singleton() { } public static synchronized Singleton getInstance() { System.out.println("...get..." + new Date()); if (instance == null) { instance = new Singleton(); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("...ret..." + new Date()); return instance; } } /** * Huisou.com Inc. * Copyright (c) 2011-2012 All Rights Reserved. */ package thread; import javax.xml.stream.events.StartDocument; /** * @description * * @author chenzehe * @email hljuczh@163.com * @create 2013-1-16 上午09:00:46 */ public class SingletonTest { public static void main(String[] args) { new Thread() { public void run() { System.out.println("run get..."); Singleton.getInstance(); } }.start(); new Thread() { public void run() { System.out.println("run get2..."); Singleton.getInstance(); } }.start(); } } run get... run get2... ...get...Wed Jan 16 09:20:12 CST 2013 ...ret...Wed Jan 16 09:20:15 CST 2013 ...get...Wed Jan 16 09:20:15 CST 2013 ...ret...Wed Jan 16 09:20:18 CST 2013
相对好点的多线程单例模式代码如下(懒汉模式):
public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; }
synchronized关键字不能继承
如果在父类中的某个方法使用了synchronized 关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上 synchronized 关键字才可以。 还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的, 但子类调用了父类的同步方法,因此,子类的方法中调用父类方法后面的代码也就相当于同步了。
接口的定义不能使用 synchronized关键字
构造方法不能使用 synchronized关键字
synchronized关键字可以放在方法访问修饰前面或后面,也可以放在static前面或后面,但是只能放在返回值前面,不能放在返回值后面,如下是正确的:
public synchronized void method();
synchronized public void method();
public static synchronized void method();
public synchronized static void method();
synchronized public static void method();
下面是错误的:
public void synchronized method();
public static void synchronized method();
使用synchronized同步代码块
synchronized块的语法:
public void method(){ ...... synchronized (锁对象){ .... } .... }
这样synchronized中的代码就会被加锁,锁对象为任意Java对象,对于非静态方法,锁对象一般为当前对象,可能用this关键字表示,对于内部类,this只表示当前内部类对象,可以使用外部类.this来表示,对于静态方法,锁对象一般使用类.class来表示,只有锁对象为同一对象时方法才会被同步,即使是在不同象中的同步方法,如果锁对象为同一对象,该同步方法也会被同步。
synchronized不能用来同步变量,如下代码是错误的:
public synchronized int i=0;
synchronized深入内容文章:聊聊并发(二)——Java SE1.6中的Synchronized
相关推荐
Java多线程synchronized关键字详解(六)共5页.pdf.zip
java多线程中synchronized关键字的用法 解压密码 www.jiangyea.com
主要介绍了Java 多线程synchronized关键字详解(六)的相关资料,需要的朋友可以参考下
Java 中多线程的同步依靠的是对象锁机制,synchronized关键字就是利用了封装对象锁来实现对共享资源的互斥访问。下面这篇文章主要介绍了java线程与synchronized关键字的相关资料,需要的朋友可以参考下。
java基本教程之synchronized关键字java多线程教程共19页.pdf.zip
开启了10个线程,每个线程都累加了...可是运行多次结果都不是这个数,而且每次运行结果都不一样。 线程安全问题主要来源于JMM的设计,主要集中在主内存和线程的工作内存而导致的内存可见性问题,以及重排序导致的问题。
主要为大家详细介绍了java多线程编程之Synchronized关键字,感兴趣的朋友可以参考一下
2. Java多线程学习(二)synchronized关键字(1) 3. Java多线程学习(二)synchronized关键字(2) 4. Java多线程学习(三)volatile关键字 5. Java多线程学习(四)等待/通知(wait/notify)机制 6. Java多...
synchronized关键字不属于方法特征签名的一部分,所以可以在覆盖方法的时候加上去。也就是说,在父类的方法声明上可以没有synchronized关键字,而在子类覆盖该方法时加上synchronized关键字。 注意:使用...
Java的synchronized关键字用于修饰线程同步,用以线程资源共享的目的等,下面就带来简单的Java多线程编程中synchronized关键字的基础用法讲解
四、 使用synchronized关键字要注意以下四点 39 五、 关于同步和锁定的一些问题 41 Java线程:并发协作-线程的交互 47 Java线程:并发协作-生产者消费者模型 52 Java线程:并发协作-死锁 55 Java线程:线程之间的...
JAVA中要想解决“脏数据”的问题,最简单的方法就是使用synchronized关键字来使run方法同步,看下面的代码,只要在void和public之间加上synchronized关键字
本篇文章提供了20道高难度的Java多线程编程面试题及详细解析,旨在帮助开发者展示出卓越的并发编程能力。在当今高并发的应用场景下,对多线程编程的理解和应用是评估面试者的重要指标。通过这些高难度问题,您将全面...
现有一成员变量 Test,当线程 A 调用 Test 的 synchronized 方法,线程 A 获得 Test 的同步锁,同时,线程 B 也去调用 Test 的 synchronized 方法,此时线程 B 无法获得 Test 的同步锁,必须等待线程 A 释放 Test 的...
1.讲解了Java多线程的基础, 包括Thread类的核心API的使用。2.讲解了在多线程中对并发访问的控制, 主要就是synchronized的使用, 由于此关键字在使用上非常灵活, 所以书中用了很多案例来介绍此关键字的使用, 为...
主要介绍了java的synchronized原理、synchronized基本规则、synchronized方法 和 synchronized代码块、实例锁和全局锁
Java多线程学习(一)Java多线程入门Java多线程学习(二)synchronized关键字(1)Java多线程学习(二)synchronized关键字(2
java基础(5.8)java高级基础之线程——synchronized关键字 本章主要讲线程,至于带上进程的原因是为了方便大家对进程和线程有个概念(咳,主要原因是鄙人也不太会进程~)。 首先简单说下我个人对进程和线程的理解。...
Java 多线程与并发(4_26)-关键字_ synchronized详解
Java多线程与线程安全实践-基于Http协议的断点续传.rar 是一个Java毕业设计项目,旨在探讨如何在Java中实现多线程下载和断点续传功能,同时确保线程安全。该项目的主要特点如下: 1. 多线程下载:项目采用了Java的...