synchronized官方定义:

同步方法支持一种简单的策略防止线程干扰和内存一致性错误,如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的(这一个synchronized关键字完成的)。

通俗的来讲:

synchronized关键字:能够保证同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。

synchronized的两个用法:

1.对象锁:包括方法锁(默认锁对象是当前实例对象)和同步代码块锁(自己指定锁的对象);

2.类锁:synchronized修饰的静态的方法或指定锁为Class对象;

代码展示:

对象锁:针对的是同一个对象(即下列中的instance对象),如果是两个不同的对象,对象锁就不能起到同步的作用(可以自己创两个对象测试),而类锁可以。

 * 对象锁的代码块形式
* @author Administrator
*
*/
public class SynchronizeTest01 implements Runnable{
static SynchronizeTest01 instance = new SynchronizeTest01();
    Object obj = new Object();
@Override
public void run() {
      //锁自定义对象
      synchronized (obj) {
            System.out.println("我是对象锁代码块,我叫"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"玩完了");
}
      //第一种锁当前对象
/*synchronized (this) {
System.out.println("我是对象锁代码块,我叫"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"玩完了");
}*/
}
public static void main(String[] args) {
Thread t1 = new Thread(instance,"线程一");
Thread t2 = new Thread(instance,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}

/**
* 普通方法锁形式
* @author Administrator
*
*/
public class SynchronizeTest02 implements Runnable{
static SynchronizeTest02 instance = new SynchronizeTest02();
@Override
public void run() {
//调用加synchronized关键字的普通方法
method();
}
public synchronized void method() {
System.out.println("我是普通方法锁,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "玩完了");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance,"线程一");
Thread t2 = new Thread(instance,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}

普通方法锁形式

类锁:每个类可能会有多个对象,但是每个类只有一个Class对象,所以类锁的本质就是对Class对象的锁,类锁在同一时刻只能被一个对象拥有(对象锁不可以)

类锁的第一种形式:在静态方法上加锁,并创建了两个对象,依然可以解决并发问题。

/**
*
* 类锁的第一种形式:静态方法锁形式
* @author Administrator
*
*/
public class SynchronizeTest02 implements Runnable{
static SynchronizeTest02 instance1 = new SynchronizeTest02();
static SynchronizeTest02 instance2 = new SynchronizeTest02();
@Override
public void run() {
//调用加synchronized关键字的静态方法
method();
}
public static synchronized void method() {
System.out.println("我是静态方法锁,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "玩完了");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance1,"线程一");
Thread t2 = new Thread(instance2,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}

类锁的第二种形式:

/**
*
* 类锁的第二种形式:代码块锁.Class形式
* @author Administrator
*
*/
public class SynchronizeTest03 implements Runnable{
static SynchronizeTest03 instance1 = new SynchronizeTest03();
static SynchronizeTest03 instance2 = new SynchronizeTest03();
@Override
public void run() {
//调用加synchronized关键字的普通方法
method();
}
public void method() {
synchronized (SynchronizeTest03.class) {
System.out.println("我是静态方法锁,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "玩完了");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(instance1,"线程一");
Thread t2 = new Thread(instance1,"线程二");
t1.start();
t2.start();
while(t1.isAlive()||t2.isAlive()) { }
System.out.println("执行结束");
}
}

锁代码块中锁.Class形式

synchronized关键字详解(一)的更多相关文章

  1. Java多线程(三)—— synchronized关键字详解

    一.多线程的同步 1.为什么要引入同步机制 在多线程环境中,可能会有两个甚至更多的线程试图同时访问一个有限的资源.必须对这种潜在资源冲突进行预防. 解决方法:在线程使用一个资源时为其加锁即可. 访问资 ...

  2. “全栈2019”Java多线程第十六章:同步synchronized关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. Java synchronized 关键字详解

    Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 sync ...

  4. 从线程池到synchronized关键字详解

    线程池 BlockingQueue synchronized volatile 前段时间看了一篇关于"一名3年工作经验的程序员应该具备的技能"文章,倍受打击.很多熟悉而又陌生的知识 ...

  5. Java 多线程(六) synchronized关键字详解

    多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题. 同步机制可以使用synchronized关键字实现. 当synchroniz ...

  6. [java] java synchronized 关键字详解

    Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一 ...

  7. 简单的互斥同步方式——synchronized关键字详解

    目录 1. 关于synchronized关键字 2. synchronized的原理和实现细节 2.1 synchronized可以用在那些地方 2.2 synchronized是如何实现线程互斥访问 ...

  8. synchronized关键字详解(二)

    synchronized关键字的性质 1.可重入:同一线程的外层函数获得锁之后,内层函数可直接再次获得该锁,好处:避免死锁,提升封装性 证明可重入粒度:1.同一个方法是可重入的 2.可重入不要求是同一 ...

  9. java关键字(详解)

    目录 1. 基本类型 1) boolean 布尔型 2) byte 字节型 3) char 字符型 4) double 双精度 5) float 浮点 6) int 整型 7) long 长整型 8) ...

随机推荐

  1. mdbtools使用

    1.导入数据库到mysql(将key.mdb导入MySQL的test数据库,此时只导入表结构) mdb-schema key.mdb mysql | mysql -u root -p test 2.将 ...

  2. android获取年月日时分秒

    Calendar calendar=Calendar.getInstance(); //获取当前时间,作为图标的名字 String year=calendar.get(Calendar.YEAR)+& ...

  3. 设置Linux使用SMTP服务发送邮件

    很多时候我们需要知道服务器的运行状态,比如发生了异常的报警.数据库备份的状态等,假如服务器自动跟你汇报那就好了,我们可以通过设置当触发某些条件时让服务器发送邮件给你,这样你就可以了解你的服务器的状态怎 ...

  4. M - Help Jimmy DP

    "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某 ...

  5. [bzoj 2463]谁能赢呢?(博弈论)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2463 分析:因为都是按最优策略,所以棋盘肯定都能走满,于是胜负关系就是判断n*n的奇偶 ...

  6. Ubuntu 16.04开机进入命令行(tty1)+分辨率调节+字体颜色设置+中文乱码解决(解决虚拟终端Ctrl+Alt+F1分辨率太大)

    一.开机进入命令行模式(tty1) sudo vim /etc/default/grub 把GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash”改成GRUB_CMDLIN ...

  7. 【Android】自己定义圆形ImageView(圆形头像 可指定大小)

    近期在仿手Q的UI,这里面常常要用到的就是圆形头像,看到 在android中画圆形图片的几种办法 这篇文章,了解了制作这样的头像的原理.只是里面提供的方法另一个不足的地方就是不能依据实际需求改变图片的 ...

  8. 微軟将弃用 System.Data.OracleClient

    http://www.cnblogs.com/WizardWu/archive/2010/05/17/1737009.html 微軟将从 .NET 4 以后的版本弃用 System.Data.Orac ...

  9. 【python】range的用法

    range的用法: >>> range(1,5) #代表从1到5(不包含5)[1, 2, 3, 4]>>> range(1,5,2) #代表从1到5,间隔2(不包含 ...

  10. ROBODK仿真如何设置运动速度

    设置工具-选项-运动,把仿真时间设置成跟正常一样   然后双击机器人,设置参数(可以设置movej和movel的速度,加速度)