synchronized 基本规则  

1. 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

class MyRunable implements Runnable {

    public void run() {
synchronized (this) { // this是指“当前的类对象” 此处为MyRunable对象 demo
try {
for (int i = 0; i < 5; i++) {
Thread.sleep(100); // 休眠100ms
System.out.println(Thread.currentThread().getName() + " loop " + i);
}
} catch (InterruptedException ie) {
}
}
}
} public class Demo1_1 { public static void main(String[] args) {
Runnable demo = new MyRunable(); // 新建“Runnable对象” Thread t1 = new Thread(demo, "t1"); // 新建“线程t1”, t1是基于demo这个Runnable对象
Thread t2 = new Thread(demo, "t2"); // 新建“线程t2”, t2是基于demo这个Runnable对象
t1.start(); // 启动“线程t1”
t2.start(); // 启动“线程t2”
}
}
===========
t1 loop 0
t1 loop 1
t1 loop 2
t1 loop 3
t1 loop 4
t2 loop 0
t2 loop 1
t2 loop 2
t2 loop 3
t2 loop 4

2.  当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块

3.  当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

  这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。

synchronized 方法 和 synchronized 代码块

(假设P1、P2是同一个类的不同对象,类中定义了同步块或同步方法,P1 P2都可以调用它。)

Public synchronized void methodA()
{
//….
}

  等同于

public void methodA()
{
synchronized (this) // this指的就是调用这个方法的对象,如P1
{
//…..
}
}

同步块:

public void method3(SomeObject so)
{
synchronized(so) // 锁是so这个对象(当有一个明确的对象作为锁时,可以这样写)
{
//…..
}
}

当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁:

class Foo implements Runnable
{
private byte[] lock = new byte[0]; // 零长度的byte数组充当锁
Public void methodA()
{
synchronized(lock) {
        //…
       }
}
//…..
}

synchronized 修饰static方法

Class Foo
{
public synchronized static void methodA() // 同步的static方法
{
//….
} public void methodB()
{
synchronized(Foo.class) // 锁当前调用这个方法的对象所属的类
}
}

methodB()方法是把class literal作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这

个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)

实例锁 和 全局锁
实例锁 -- 锁在某一个实例对象上。如果该类是单例,那么该锁也具有全局锁的概念。 实例锁对应的就是synchronized关键字。
全局锁 -- 该锁针对的是类,无论实例多少个对象,那么线程都共享该锁。 全局锁对应的就是static synchronized(或者是锁在该类的class或者classloader对象上)。

// 举例
pulbic class Something {
public synchronized void isSyncA(){}
public synchronized void isSyncB(){}
public static synchronized void cSyncA(){}
public static synchronized void cSyncB(){}
} 假设,Something有两个实例x和y。分析下面4组表达式获取的锁的情况。
(1) x.isSyncA()与x.isSyncB() // 不能同时访问,都是锁的对象x
(2) x.isSyncA()与y.isSyncA()        // 可以同时访问,锁的不是同一个对象
(3) x.cSyncA()与y.cSyncB()         // 不能同时访问,static方法,两个都相当于Something.isSyncA()。锁的同一个类
(4) x.isSyncA()与Something.cSyncA()    // 可以同时访问,x.isSyncA()使用的是对象x的锁;而cSyncA()是静态方法,Something.cSyncA()可以理解对使用的是“类的锁”。

java基础温习 -- Thread synchronized关键字的更多相关文章

  1. java基础温习 -- Thread

    启动线程两种方式: 1. 实现Runnable接口: 2. 继承Thread类. 选用:能使用接口,就不用从Thread类继承.    使用继承的方法不够灵活,从这个类继承了就不能从其他类继承: 实现 ...

  2. JAVA多线程之Synchronized关键字--对象锁的特点

    一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...

  3. Java并发编程(一):线程基础知识以及synchronized关键字

    1.线程与多线程的概念:在一个程序中,能够独立运行的程序片段叫作“线程”(Thread).多线程(multithreading)是指从软件或者硬件上实现多个线程并发执行的技术. 2.多线程的意义:多线 ...

  4. Java多线程4:synchronized关键字

    原文:http://www.cnblogs.com/skywang12345/p/3479202.html 1. synchronized原理在java中,每一个对象有且仅有一个同步锁.这也意味着,同 ...

  5. 搜狗一道java题目 关于对象 synchronized 关键字作用在 int, integer

      第一次见到这个题目,我觉得自己没学到java,太浅了,其实这个问题没有考synchronized关键字,只是考什么是对象? 1.在java编程思想的第二章有一句话; 一切都是对象,很可惜int,c ...

  6. java线程学习之synchronized关键字

    关键字synchronized的作用是实现线程间的同步.它的任务是对同步的代码加锁.一个代码块同时只能有同一个线程进行读和写操作,从而保证线程间是安全的. 线程安全的概念是:当多个线程访问某一个类(对 ...

  7. Java 基础(6)——关键字 & 标识符 & 转义字符

    依然是基础的一天,看一看就好~ 关键字 之前就有说过关键字哦~ 注:关键字就是程序发明者规定的有特殊含义的单词. from Java基础(2) Java 中除了关键字以外还有暂时没有成为关键字的保留字 ...

  8. 2.3多线程(java学习笔记)synchronized关键字

    一.为什么要用synchronized关键字 首先多线程中多个线程运行面临共享数据同步的问题. 多线程正常使用共享数据时需要经过以下步骤: 1.线程A从共享数据区中复制出数据副本,然后处理. 2.线程 ...

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

    想必在面试中经常会被问到Synchronized关键字,它有什么特性,原理什么 它的主要特性是同步锁.非公平锁.阻塞锁.可以保证线程安全(可见性.原子性.有序性) JDK1.6之后对Synchroni ...

随机推荐

  1. 006-Java的break和continue

    break 和 continue关键字的使用 break: 结束当前循环 continue:结束当次循环 示例如下 class JavaTest{ public static void main(St ...

  2. Spark三种部署方式

  3. 笔记:Python防止SQL注入

    非安全的方式,使用动态拼接SQL 输入' or 1 = 1 or '1 sql ="""SELECT * FROM goods WHERE name = '%s';&qu ...

  4. Java学习 时间类 Period类与Duration类 / LocalDate类与Instant类 用法详解

    前言 java 8 中引入的两个与日期相关的新类:Period 和 Duration.两个类看表示时间量或两个日期之间的差,两者之间的差异为:Period基于日期值,而Duration基于时间值.他们 ...

  5. 2019.12.04 Java中的内存分配

    Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般 ...

  6. yum -y install python-devel

    yum -y install python-devel的时候报错如图: Could not retrieve mirrorlist http://mirrorlist.centos.org/?rele ...

  7. [JZOJ6344] 【NOIP2019模拟2019.9.7】Huge Counting

    题目 题目大意自己看题去-- 正解 比赛时在刚第二题,所以根本没有时间思考-- 模型可以转化为从\((x_1,x_2,..,x_n)\)出发到\((1,1)\)的方案数模\(2\). 方案数就用有重复 ...

  8. hadoop快照管理

    快照相当于对目录做备份,并不会复制所有文件,而是记录文件的变化命令用法 ()hdfs dfsadmin -allowSnapshot 路径 (开启指定目录的快照功能) ()hdfs dfsadmin ...

  9. linux如何查看防火墙是否开启?删除iptables规则

    iptables是linux下的防火墙组件服务,相对于windows防火墙而言拥有更加强大的功能,此经验咗嚛以centos系统为例.关于iptables的一般常见操作,怎么来判断linux系统是否启用 ...

  10. 一篇关于Matcher find方法深刻理解的文章

    文章目录 知识点 find find(int var1) reset group(int var1) 源码 故事是这样的 探索 问题解决 方法一: 方法二: 方法三: 总结 知识点 find 首先fi ...