关于synchronized有趣的同步问题

在多线程对一个整数进行自增操作时,需要用synchronized进行同步。然而,如果synchronized的对象选取的不合适的话,就无法实现同步的效果。如下面的例子。

public class SyncThreadTest extends Thread {
  public static Integer count = 0;
  private static final int TIMES = 10000;
  public SyncThreadTest(){
    super("SyncThread");
  }
  @Override
  public void run(){
    synchronized (count){
      for (int i = 0; i < TIMES; i ++){
        count++;
      }
    }
  }
  public static void main(String[] args) throws InterruptedException{
    SyncThreadTest t1 = new SyncThreadTest();
    SyncThreadTest t2 = new SyncThreadTest();
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(count);
  }
}

在上面的例子中,选取了自增的变量作为同步的对象。启动2个线程,各自对count自增10000次。最后的结果,count的值却不是20000次。

原因在于count对象一直处于改变当中,起不到两个线程的锁的作用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • Java线程公平锁和非公平锁的差异讲解

    公平锁,顾名思义,它是公平的,可以保证获取锁的线程按照先来后到的顺序,获取到锁. 非公平锁,顾名思义,各个线程获取到锁的顺序,不一定和它们申请的先后顺序一致,有可能后来的线程,反而先获取到了锁. 在实现上,公平锁在进行lock时,首先会进行tryAcquire()操作.在tryAcquire中,会判断等待队列中是否已经有别的线程在等待了.如果队列中已经有别的线程了,则tryAcquire失败,则将自己加入队列.如果队列中没有别的线程,则进行获取锁的操作. /** * Fair version o

  • Java源码解析之可重入锁ReentrantLock

    本文基于jdk1.8进行分析. ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLock. 首先看一下源码中对ReentrantLock的介绍.如下图.ReentrantLock是一个可重入的排他锁,它和synchronized的方法和代码有着相同的行为和语义,但有更多的功能.ReentrantLock是被最后一个成功lock锁并且还没有unlock的线程拥有着.如果锁没有被别的线程拥有,那么一个线程调用lock方法,就会成功获取锁并返回.

  • 透彻理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别

    本文讲述了Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别.分享给大家供大家参考,具体如下: Synchronized和Static Synchronized区别 通过分析这两个用法的分析,我们可以理解java中锁的概念.一个是实例锁(锁在某一个实例对象上,如果该类是单例,那么该锁也具有全局锁的概念),一个是全局锁(该锁针对的是类,无论实例多少个对象,那么线程都共享该锁).实例锁对应的就是synchronized关键字,而类锁(全局锁)对应的就是

  • Java可重入锁的实现原理与应用场景

    可重入锁,从字面来理解,就是可以重复进入的锁. 可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响. 在JAVA环境下ReentrantLock和synchronized都是可重入锁. synchronized是一个可重入锁.在一个类中,如果synchronized方法1调用了synchronized方法2,方法2是可以正常执行的,这说明synchronized是可重入锁.否则,在执行方法2想获取锁的时候,该锁已经在执行方法1时获取了,那么方法

  • 深入理解java内置锁(synchronized)和显式锁(ReentrantLock)

    synchronized 和 Reentrantlock 多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两种同步方式.显式锁是JDK1.5引入的,这两种锁有什么异同呢?是仅仅增加了一种选择还是另有其因?本文为您一探究竟. // synchronized关键字用法示例 public synchronized void add(int t){// 同步方法 this.v += t; } public stati

  • Java多线程产生死锁的必要条件

    线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行.当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块.当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁. 死锁是操作系统里里面的一个重要的概念,死锁通常发生在并发的场景里. 死锁是多个进程或线程,彼此争抢资源而陷入僵局的一种情况. 在笔者参加的多次

  • Java关键字volatile和synchronized作用和区别

    volatile是变量修饰符,而synchronized则是作用于一段代码或方法:如下三句get代码: int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值.多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同.换句话说,另一个线程可能已经改变了它线程内的i1

  • 使用synchronized实现一个Lock代码详解

    刚看到这个题目的时候无从下手,因为觉得synchronized和lock在加锁的方式上有很大不同,比如,看看正常情况下synchronized时如何加锁的. 方式一: public synchronized void a(){ //TODO } 方式二: public void b(){ synchronized(this){ //TODO } } 从这两种方式来看,锁都是加在{}之间的,我们再来看看Lock是如何做的呢: public void c() { lock.lock(); try {

  • Java分布式锁的概念与实现方式详解

    什么是分布式锁?在回答这个问题之前,我们先回答一下什么是锁. 普通的锁,即在单机多线程环境下,当多个线程需要访问同一个变量或代码片段时,被访问的变量或代码片段叫做临界区域,我们需要控制线程一个一个的顺序执行,否则会出现并发问题. 如何控制呢?就是设置一个各个线程都能看的见的标志.然后,每个线程想访问临界区域时,都要先查看标志,如果标志没有被占用,则说明目前没有线程在访问临界区域.如果标志被占用了,则说明目前有线程正在访问临界区域,则当前线程需要等待. 这个标志,就是锁. 在单机多线程的java程

  • jvm细节探索之synchronized及实现问题分析

    在C程序代码中我们可以利用操作系统提供的互斥锁来实现同步块的互斥访问及线程的阻塞及唤醒等工作.然而在Java中除了提供LockAPI外还在语法层面上提供了synchronized关键字来实现互斥同步原语.那么到底在JVM内部是怎么实现synchronized关键子的呢? 一.synchronized的字节码表示: 在java语言中存在两种内建的synchronized语法:1.synchronized语句:2.synchronized方法.对于synchronized语句当Java源代码被jav

随机推荐