java多线程中的volatile和synchronized用法分析

本文实例分析了java多线程中的volatile和synchronized用法。分享给大家供大家参考。具体实现方法如下:

代码如下:

package com.chzhao;

public class Volatiletest extends Thread {

private static int count = 0;

public void run() {
        count++;
    }

public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Volatiletest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

代码如上,期待输出的是10000,然后,由于count++不是线程安全的,所以输出经常会小于10000.

为了解决这个问题,增加了volatile关键字。

代码如下:

package com.chzhao;

public class Volatiletest extends Thread {

private volatile static int count = 0;

public void run() {
        count++;
    }

public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Volatiletest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

修改之后,还经常输出不是10000的值。

修改为synchronized形式,代码如下:

代码如下:

package com.chzhao;

public class SynchronizedTest extends Thread {
    private static int count = 0;

public void run() {
        synchronized (LockClass.lock) {
            count++;
        }
    }

public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new SynchronizedTest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

代码如下:

package com.chzhao;

public class LockClass {
    public static byte[] lock = new byte[0];

}

这样修改之后,输出是10000.

这样是否说明volatile这个关键字完全没用呢?只有synchronized才能保证线程安全?

说明:

Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。这两种机制的提出都是为了实现代码线程的安全性。其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。

也就是说,在某些情况下,volitile比synchronized用起来更方便,当然,同步性更差一点。

希望本文所述对大家的Java程序设计有所帮助。

(0)

相关推荐

  • java中volatile和synchronized的区别与联系

    java中volatile和synchronized的区别与联系 这个可能是最好的对比volatile和synchronized作用的文章了.volatile是一个变量修饰符,而synchronized是一个方法或块的修饰符.所以我们使用这两种关键字来指定三种简单的存取变量的方式 int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {

  • 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

  • java多线程中的volatile和synchronized用法分析

    本文实例分析了java多线程中的volatile和synchronized用法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: package com.chzhao; public class Volatiletest extends Thread { private static int count = 0; public void run() {         count++;     } public static void main(String[] args) {  

  • java多线程编程必备volatile与synchronized深入理解

    目录 Volatile概述 Synchronized概述 Volatile与Synchronized的区别 使用场景 1 Volatile的使用场景 2 Synchronized的使用场景 注意事项 相关面试问题 Volatile概述 Volatile是Java中的一种轻量级同步机制,用于保证变量的可见性和禁止指令重排.当一个变量被声明为Volatile类型时,任何修改该变量的操作都会立即被所有线程看到.也就是说,Volatile修饰的变量在每次修改时都会强制将修改刷新到主内存中,具有很好的可见

  • 深入探讨Java多线程中的volatile变量

    volatile 变量提供了线程的可见性,并不能保证线程安全性和原子性. 什么是线程的可见性: 锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility).互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据.可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 -- 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前

  • Java多线程中Lock锁的使用总结

    多核时代 摩尔定律告诉我们:当价格不变时,集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍.换言之,每一美元所能买到的电脑性能,将每隔18个月翻两倍以上.然而最近摩尔定律似乎遇到了麻烦,目前微处理器的集成度似乎到了极限,在目前的制造工艺和体系架构下很难再提高单个处理器的速度了,否则它就被烧坏了.所以现在的芯片制造商改变了策略,转而在一个电路板上集成更多的处理器,也就是我们现在常见的多核处理器. 这就给软件行业带来麻烦(也可以说带来机会,比如说就业机会,呵呵).原来的情况

  • Java多线程中线程间的通信实例详解

    Java多线程中线程间的通信 一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.util.List; public class MyList { private volatile static List list = new ArrayList(); public void add() { list.add("apple"); } publ

  • Java多线程中不同条件下编写生产消费者模型方法介绍

    简介: 生产者.消费者模型是多线程编程的常见问题,最简单的一个生产者.一个消费者线程模型大多数人都能够写出来,但是一旦条件发生变化,我们就很容易掉进多线程的bug中.这篇文章主要讲解了生产者和消费者的数量,商品缓存位置数量,商品数量等多个条件的不同组合下,写出正确的生产者消费者模型的方法. 欢迎探讨,如有错误敬请指正 生产消费者模型 生产者消费者模型具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品.生产消费者模式

  • Java多线程中ReentrantLock与Condition详解

    一.ReentrantLock类 1.1什么是reentrantlock java.util.concurrent.lock中的Lock框架是锁定的一个抽象,它允许把锁定的实现作为Java类,而不是作为语言的特性来实现.这就为Lock的多种实现留下了空间,各种实现可能有不同的调度算法.性能特性或者锁定语义.ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,但是添加了类似锁投票.定时锁等候和可中断锁等候的一些特性.此外,它还提供了在激烈争用情况下更

  • Java多线程中Lock锁的使用小结

    Lock基本使用 Lock它是java.util.concurrent.locks下的一个接口,它也是用来处理线程同步问题的. public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void

  • Java多线程中的单例模式两种实现方式

    Java多线程中的单例模式 一.在多线程环境下创建单例 方式一: package com.ietree.multithread.sync; public class Singletion { private static class InnerSingletion { private static Singletion single = new Singletion(); } public static Singletion getInstance() { return InnerSinglet

  • java多线程之线程,进程和Synchronized概念初解

    一.进程与线程的概念 (1)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程. 在未配置 OS 的系统中,程序的执行方式是顺序执行,即必须在一个程序执行完后,才允许另一个程序执行:在多道程序环境下,则允许多个程序并发执行.程序的这两种执行方式间有着显著的不同.也正是程序并发执行时的这种特征,才导致了在操作系统中引入进程的概念. 自从在 20 世纪 60 年代人们提出了进程的概念后,在 OS 中一直都是以进程作为能拥有资源和独立运行的基本单位的.直到 20 世纪 8

随机推荐