二、synchronized

1.共享、可变。

偷个懒,下面是《java并发编程实战》的一段:

当我第一次看到这段话的时候,确实有点晕。
对象的状态:成员变量、static变量以及其他依赖对象的域都是对象的状态。
如果一个对象是无状态的(既没有成员变量和static变量,也没有其他依赖对象的域),那么这个对象绝对是线程安全的。

共享:意味着对象的状态可以由多个线程同时访问。变量共享说明你的变量可以直接或者通过方法(例如:getXXX()方法)间接的访问。
可变:意味着变量的值在其生命周期内可以发生变化。
一个对象是否需要线程安全,取决于是否被多个线程访问。
如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误。

2.内置锁

java提供了一种内置锁机制来支持原子性:同步代码块(Synchronized Block)。同步代码块包括两部分:一个作为锁的对象引用,一个作为锁保护的代码块。以关键字synchronized修饰的方法,它的锁的对象引用就是方法调用所在的对象(哪个对象调用,就以哪个对象作为锁),而代码块为整个方法体。静态synchronized方法以Class对象作为锁。

synchronized(obj){ //以obj为锁对象
         //同步代码块
}

每个java都可以用做一个实现同步的锁,这些锁被称为内置锁或监视锁。线程进入同步代码块之前会自动获得锁,并且在退出同步代码块时自动释放锁,而无论是正常退出,还是抛异常退出。获得内置锁的唯一途径就是进入这个锁保护的同步代码块或方法。

每一个内置锁都是互斥锁,这就意味着最多只有一个线程能持有这种锁。

synchronized(c){
 ....    a同步代码块
}

//当一个线程X走到这里时,如果已经有一个线程Y进入a同步代码块(或者b同步代码块)获得以c锁对象的内置锁,那么这个线程X必须等待或者阻塞
synchronized(c){
 ....    a同步代码块
}

重入:如果某个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。

class A {
  public synchronized void hehe(){
    System.out.println("A");
  }
}

public class B extends A{
  public synchronized void hehe(){
   System.out.println("B");
   super.hehe();   //父类的hehe()方法也加了synchronized,这里是可重入的。
  }
}
时间: 2025-01-12 18:29:44

二、synchronized的相关文章

二十二 synchronized同步方法

一 Synchronized锁: 1 synchronized取得的锁都是对象锁,而不是把一段代码或方法加锁. synchronized是给该方法的实例对象加锁.如果多个线程访问的是同一个对象  的synchronized方法,就可以同步. 2 对象中的非synchronized类型的方法是不需要等待锁的. 3 不同的synchronized方法之间也是互斥的,因为锁的是对象! 二 Synchronized锁重入: synchronized具有锁重入的功能,同一个线程可以多次获得一个对象的锁.也

Java多线程之二(Synchronized)

常用API method 注释 run() run()方法是我们创建线程时必须要实现的方法,但是实际上该方法只是一个普通方法,直接调用并没有开启线程的作用. start() start()方法作用为使该线程开始执行:Java虚拟机调用该线程的 run 方法. 但是该方法只能调用一次,如果线程已经启动将会抛出IllegalThreadStateException异常. yield() yield()方法让出CPU并且不会释放锁,让当前线程变为可运行状态,所以CPU下一次选择的线程仍可能是当前线程.

Java基础学习笔记二十一 多线程

多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程.一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序. 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 什么是多线程呢?即就是一个程序中有多个线程在同时执行.通过下图来区别单线程程序与

java concurrent之ReentrantLock

在编码的过程中,有时候我们不得不借助锁同步来保证线程安全.synchronized关键字在上一篇博客中已经介绍:自从JDK5开始,添加了另一种锁机制:ReentrantLock. 二者的区别 1.lock是jdk5之后代码层面实现的,synchronized是JVM层面实现的. 2.synchronized在出现异常的时候能够自动释放锁,而lock必须在finally块中unlock()主动释放锁,否则会死锁. 3.在竞争不激烈的时候synchronized的性能是比lock好一点的,但是当竞争

Java 多线程序的一点理解

synchronized 是java 内主要的同步标记 1 同步非静态方法 作用域范围只是当前对象在不同线程间的同步, 如果n 为Test外的对象,在不同的Test对象之间,等于没有同步, 该方法只能同步n为Test类内对象 public class Test public synchronized void inc() { n++; } } 如果想同步类外的n,使用同步代码块对象,对象也为一个类外对象,相对所有Test对象来说, 也只有一个,所以就能同步 final Integer lock

JavaSE学习53:细说多线程之内存可见性

一共享变量在线程间的可见性 (1)有关可见性的一些概念介绍 可见性:一个线程对共享变量值的修改,能够及实地被其他线程看到. 共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量.所 有的变量都存储在主内存中. 线程的工作内存:每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中该变量的 一份拷贝). (2)数据争用问题 多个线程对同一资源操作时,通常会产生进程,比如一个线程往消息队列插入数据,而另一个线程从消息队列取 出数据 当消息队

多线程序的角度理解静态类

通常称为嵌套类,当内部类是static时,意味着: 1  要创建嵌套类的对象,并不需要其外围类的对象 2 不能从嵌套类的对象中访问非静态的外围类对象(不能够从静态内部类的对象中访问外部类的非静态成员) 在创建静态内部类时不需要将静态内部类的实例绑定在外部类的实例上.普通非静态内部类的对象是依附在外部类对象之中的,要在一个外部类中定义一个静态的内部类,不需要利用关键字new来创建内部类的实例.静态类和方法只属于类本身,并不属于该类的对象,更不属于其他外部类的对象, 所以只能访问外部类的静态方法.

JAVA-基础-线程安全

线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 我们通过一个案例,演示线程的安全问题: 电影院要卖票,我们模拟电影院的卖票过程.假设要播放的电影是 "功夫熊猫3",本次电影的座位共100个(本场电影只能卖100张票). 我们来模拟电影院的售票窗口,实现多个窗口同时卖 "功夫熊猫3"这场电影票(多个窗口一起卖这100张票) 需要窗口,采用线程对象来

java多线程(二)——锁机制synchronized(同步方法)

synchronized Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块.然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块. ——以上来源百度百科 一.方法内的变量为线程安全 “非线程安全”的问题

Java程序设计之合租房synchronized(二)

一号和二号合租一间房,里面共用一个卫生间对象,这是要用到synchronized关键字,一号与二号同时使用卫生间时,一个需要wait()等待被唤醒,另外一个使用完之后卫生间对象被释放,这时候刚刚使用的需要进入wait()状态,否则会造成死锁现象,卫生间资源释放之后,还需要唤醒另一个正在监听此对象的线程. 首先构造一个房间类Room,内部构造一号和二号的对象,Object一个卫生间类,当作被线程监听的类,使用synchronized关键字: synchronized (toliet) {} 此时t