`
firkeuuuu
  • 浏览: 18578 次
社区版块
存档分类
最新评论

500线程同时操作int对象【java多线程共享变量】

    博客分类:
  • java
 
阅读更多

一、异常情况

   500个线程同时操纵变量number,执行number++操作,结果并不一定等于500。

   无论是否使用volatile 修饰number,结果都一样。

public class VolatileTest {
    public static volatile int number = 0;
    public void increase(){
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        number++;
    }
    
    public static void main(String[] args) {
        final VolatileTest test = new VolatileTest();
        for(int i = 0 ; i < 500 ; i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test.increase();
                }
            }).start();
        }
        //若当期依然有子线程没有执行完毕
        while(Thread.activeCount() > 2){
            //使得当前线程(主线程)让出CPU时间片
            Thread.yield();
        }
        System.out.println("number is " + number);
    }
}

 

二、改进方式

   2.1使用synchronized

 

 public void increase(){
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized(this){
            number++;
        }
    }

 

   2.2使用ReentrantLock

 

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class VolatileTest {
    public static  int number = 0;
    public Lock lock =  new ReentrantLock();

    public void increase(){
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        lock.lock();
        try{
            number++;
        }finally{
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        final VolatileTest test = new VolatileTest();
        for(int i = 0 ; i < 500 ; i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test.increase();
                }
            }).start();
        }
        //若当期依然有子线程没有执行完毕
        while(Thread.activeCount() > 2){
            //使得当前线程(主线程)让出CPU时间片
            Thread.yield();
        }
        System.out.println("number is " + number);
    }
}

   2.3 AtomicInteger

    AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口

 

import java.util.concurrent.atomic.AtomicInteger;

public class VolatileTest {
    public static AtomicInteger number = new AtomicInteger(0);

    public void increase(){
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        number.getAndIncrement();//获得当前值并且加1
    }

    public static void main(String[] args) {
        final VolatileTest test = new VolatileTest();
        for(int i = 0 ; i < 500 ; i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test.increase();
                }
            }).start();
        }
        //若当期依然有子线程没有执行完毕
        while(Thread.activeCount() > 2){
            //使得当前线程(主线程)让出CPU时间片
            Thread.yield();
        }
        System.out.println("number is " + number);
    }
}

 

三、volatile适用情况

    对变量的写入操作不依赖当前值 
         比如自增自减、number = number + 5等(不满足)
    当前volatile变量不依赖于别的volatile变量
        比如 volatile_var > volatile_var2这个不等式(不满足)

 四、synchronized和volatile比较

    volatile不需要同步操作,所以效率更高,不会阻塞线程,但是适用情况比较窄 

    volatile读变量相当于加锁(即进入synchronized代码块),而写变量相当于解锁(退出synchronized代码块)
    synchronized既能保证共享变量可见性,也可以保证锁内操作的原子性;volatile只能保证可见性
分享到:
评论

相关推荐

    java多线程的讲解和实战

    Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...

    java多线程进度条

    一个简单的进度条实现可以采用共享变量(如int progress)和锁机制。工作线程在执行任务时会更新进度,而主线程通过循环检查进度并在UI上更新进度条。为了防止竞争条件,我们需要在读写进度变量时进行同步控制,例如...

    java多线程编程-详细炒作例子

    ### Java多线程编程详解与实战案例 #### 理解多线程概念与Java内存模型 多线程,作为现代编程中的一项关键技术,允许在单一应用程序中并发执行多个指令流,每个这样的指令流被称为一个线程。在Java中,线程被视为...

    多线程java买票系统

    2. **Java多线程实现方式** - 继承`Thread`类:创建一个新的类,继承自`Thread`,重写`run()`方法,然后创建该类的实例并调用`start()`方法启动线程。 - 实现`Runnable`接口:创建一个新的类实现`Runnable`接口,...

    JAVA多线程编程详解-详细操作例子(转自CSDN)

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提升程序的效率和响应性。本文将详细解析Java中实现多线程的两种主要方式,并讨论线程的基本概念和内存模型。 首先,理解多线程的概念至关...

    java实现多线程下载

    2. **Java多线程实现**: - 实现方式一:继承`Thread`类。创建一个新的类,继承自`Thread`,重写`run()`方法,然后创建该类的实例并调用`start()`方法启动线程。 - 实现方式二:实现`Runnable`接口。创建一个类,...

    java多线程笔记全手打

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的运行效率和资源利用率。本笔记全面涵盖了多线程的学习,包括基础理论和实践代码,旨在帮助开发者深入理解并掌握Java多线程技术。 一、...

    java多线程编程总结

    ### Java多线程编程总结 #### 一、Java线程:概念与原理 - **操作系统中线程和进程的概念** 当前的操作系统通常都是多任务操作系统,多线程是一种实现多任务的方式之一。在操作系统层面,进程指的是内存中运行的...

    Java多线程示例 可以直接运行

    Java多线程是Java编程中的重要组成部分,它允许程序同时执行多个任务,从而提升系统效率。在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。本示例提供了可以直接运行的Java多线程代码,帮助...

    java多线程并发

    ### Java多线程并发知识点详解 #### 一、Java多线程并发简介 在现代软件开发中,特别是在Java这样的主流编程语言中,多线程并发技术是提高程序执行效率、优化资源利用的关键手段之一。本篇文章将深入探讨Java中的...

    Java 多线程 订票 示例 线程安全

    总结起来,Java多线程在实现订票系统时,需要注意线程安全问题,通过合理使用同步机制、Lock接口和原子类,可以在保证数据一致性的同时提高并发性能。在实际开发中,要根据业务场景选择合适的线程安全策略,以达到...

    Java多线程 - (一) 最简单的线程安全问题

    在Java编程中,多线程是并发处理任务的关键技术,特别是在服务器端开发和高并发场景下。本篇文章将深入探讨“最简单的线程安全问题”,并结合相关源码和工具来帮助理解。线程安全问题通常涉及到多个线程对共享资源的...

    最好的java多线程电子书

    ### 最好的Java多线程电子书 #### 一、并发与多任务 - **并发**:指在同一时间段内,系统能够处理多个任务的能力。在计算机领域中,这意味着多个任务看起来像是同时进行的,但实际上可能是通过快速切换的方式实现...

    JAVA多线程机制

    Java多线程机制是Java编程中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算机系统中,多线程是实现并发处理的关键技术,尤其在服务器端应用和高性能计算中不可或缺。本文...

    Java多线程与线程安全实践-基于Http协议的断点续传.zip

    总的来说,Java多线程与线程安全实践对于理解和实现基于HTTP协议的断点续传功能至关重要。通过合理地运用多线程、同步机制和原子变量,可以构建出高效、安全的并发应用程序。这个实践项目会深入讲解这些概念,并提供...

    Java多线程 例题

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而提升软件的效率和响应性。在Java中实现多线程有两种主要方式:通过实现`Runnable`接口或者继承`Thread`类。本例题将深入探讨Java多线程的相关...

    java多线程操作简单示例

    ### Java多线程操作简单示例 #### 一、引言 Java作为一种广泛使用的编程语言,其多线程特性为其提供了强大的并发处理能力。通过合理地利用多线程技术,可以显著提高应用程序的性能和响应速度。本文将通过一个简单...

    《Java多线程编程实例》随书源码

    在Java编程领域,多线程是一项至关重要的技术,它允许程序同时执行多个任务,从而提高系统资源的利用率...通过实际操作,开发者能更好地理解和掌握Java多线程的精髓,为编写高效、稳定、安全的多线程程序打下坚实基础。

Global site tag (gtag.js) - Google Analytics