多线程范围内的数据共享

多线程范围内的共享解决方法参考有4中:

1.如果线程执行的代码相同,多个线程共享同一个runnable对象时,将共享数据放在runnable对象

2.如果多个线程执行的代码不同,将共享数据封装到一个对象中,将这个对象逐一传递给各个runnable对象

3.如果多个线程执行的代码不同,将共享数据作为外部类的final成员变量,将不同的runnable对象作为内部类主动取数据

4.将数据声明为static的方式()

见如下示例:

1.如果线程执行的代码相同,多个线程共享同一个runnable对象时,将共享数据放在runnable对象

public class MuiltThreadShare {
    /**
     * 多个线程共享数据方法:
     * 1.如果线程执行的代码相同,多个线程共享同一个runnable对象时,将共享数据放在runnable对象
     * 2.如果多个线程执行的代码不同,将共享数据封装到一个对象中,将这个对象逐一传递给各个runnable对象
     * 3.如果多个线程执行的代码不同,将共享数据作为外部类的final成员变量,将不同的runnable对象作为内部类主动取数据
     */

    public static void main(String[] args) {
        //1.方式一
        Task1 task1 = new Task1();
        new Thread(task1).start();
        new Thread(task1).start();
        new Thread(task1).start();

    }

}

class Task1 implements Runnable{
    /**
     * 1.如果线程执行的代码相同,多个线程共享同一个runnable对象时,将共享数据放在runnable对象
     */

    private int i = 100;

    @Override
    public void run() {
        increase();
        decrease();
    }

    private synchronized void increase(){
        try {
            Thread.sleep(200);//为了更容易看到线程执行现象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        i++;
        System.out.println(Thread.currentThread().getName() +",num:"+i);
    }
    private synchronized void decrease(){
        i--;
        System.out.println(Thread.currentThread().getName() +",num:"+i);
    }

运行结果:最终还是100,不同的线程使用共享数据

运行结果
//    Thread-0,num:101
//    Thread-2,num:102
//    Thread-1,num:103
//    Thread-2,num:102
//    Thread-0,num:101
//    Thread-1,num:100

2.如果多个线程执行的代码不同,将共享数据封装到一个对象中,将这个对象逐一传递给各个runnable对象

public class MuiltThreadDataShare2 {
    public static void main(String[] args) {
        // 2.如果多个线程执行的代码不同,将共享数据封装到一个对象中,将这个对象逐一传递给各个runnable对象
        /**
         * 模拟银行转账功能,可以指定存取款金额,账号初始额度100
         */
        ShareData data = new ShareData(0);

        // 存50元
        new Thread(new TaskIncrease(data, 50)).start();
        // 取30元
        new Thread(new Taskdecrease(data, 30)).start();
        // 存20
        new Thread(new TaskIncrease(data, 20)).start();

    }

}

class Taskdecrease implements Runnable {
    public Taskdecrease(ShareData shareData, int num) {
        this.shareData = shareData;
        this.num = num;
    }

    private int num;

    private ShareData shareData;

    @Override
    public void run() {
        shareData.decrease(num);
    }

}

class TaskIncrease implements Runnable {
    public TaskIncrease(ShareData shareData, int num) {
        this.shareData = shareData;
        this.num = num;
    }

    private ShareData shareData;
    private int num;

    @Override
    public void run() {
        shareData.increase(num);
    }

}

class ShareData {
    public ShareData(int num) {
        i = num;
        System.out.println("账户进行初始化,金额为:" + num);
    }

    private int i;

    public synchronized void increase(int i) {
        try {
            Thread.sleep(200);// 为了更容易看到线程执行现象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.i = this.i + i;
        System.out.println(Thread.currentThread().getName() + "账户存入" + i + "元,目前账户余额为:" + this.i);
    }

    public synchronized void decrease(int i) {
        this.i = this.i - i;
        System.out.println(Thread.currentThread().getName() + "账户取出" + i + "元,目前账户余额为:" + this.i);
    }
}

运行结果:

账户进行初始化,金额为:0
Thread-0账户存入50元,目前账户余额为:50
Thread-2账户存入20元,目前账户余额为:70
Thread-1账户取出30元,目前账户余额为:40

3.如果多个线程执行的代码不同,将共享数据作为外部类的final成员变量,将不同的runnable对象作为内部类主动取数据

public class MuiltThreadDataShare3 {

    public static void main(String[] args) {
        final Data data = new Data();
        new Thread(new Runnable() {
            @Override
            public void run() {
                data.decrease(10);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                data.increase(30);
            }
        }).start();

    }

}

class Data {
    private int money = 100;

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public synchronized void increase(int i) {
        try {
            Thread.sleep(200);// 为了更容易看到线程执行现象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.money = this.money + i;
        System.out.println(Thread.currentThread().getName() + "账户存入" + i + "元,目前账户余额为:" + this.money);
    }

    public synchronized void decrease(int i) {
        this.money = this.money - i;
        System.out.println(Thread.currentThread().getName() + "账户取出" + i + "元,目前账户余额为:" + this.money);
    }

}

4.将数据声明为static的方式

public class MuiltThreadDataShare4 {
    private static int num = 100;

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                increase(100);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                decrease(30);
            }
        }).start();
    }

    public static synchronized void increase(int i) {
        try {
            Thread.sleep(200);// 为了更容易看到线程执行现象
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        num = num + i;
        System.out.println(Thread.currentThread().getName() + "账户存入" + i + "元,目前账户余额为:" + num);
    }

    public static synchronized void decrease(int i) {
        num = num - i;
        System.out.println(Thread.currentThread().getName() + "账户取出" + i + "元,目前账户余额为:" + num);
    }

}

时间: 2024-08-01 02:36:12

多线程范围内的数据共享的相关文章

多线程之线程范围内的数据共享ThreadLocal

如果多个线程使用同一个数据,那么如何保证线程范围内的数据共享. 我们可以使用一个map来存储当前线程,以及其数据如下: package andy.thread.traditional.test; import java.util.HashMap; import java.util.Map; import java.util.Random; /** * @author Zhang,Tianyou * @version 2014年11月8日 下午2:12:44 */ // 线程范围内的共享数据 pu

单线程范围内的数据共享_ThreadLocal

单线程范围内数据共享使用ThreadLocal /** * @Description TODO * @author [email protected] * @since 2015年12月12日 * @version V1.0 */ public class DataShare { /** * ThreadLocal:保存和当前线程相关的变量数据 * 线程范围内的数据共享 ThreadLocal * 优雅的设计方式,Person * 每一个线程使用完毕要清空ThreadLocal保存的当前变量 *

4、线程范围内的数据共享之ThreadLocal

1 /** 2 * 线程范围类的数据共享 3 * 核心:ThreadLocal类 4 * 实际场景: 5 * Hibernate的getCurrentSession方法,就是从线程范围内获取存在的session,如果不存在则新建一个并绑定到线程上 6 * struts将一个请求里的所有参数绑定到一个线程范围内的对象里 7 * @author yzl 8 * 9 */ 10 public class ThreadPart_4 { 11 public static void main(String[

多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)

ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.JDK 1.2的版本中就提供java.lang.ThreadLocal,使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量. 1.下图和辅助代码解释ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据. 2.每个线程调用全局ThreadLocal

JAVA多线程提高三:线程范围内共享变量&ThreadLocal

今天我们学习的是如何在线程自己的范围内达到变量数据的共享,而各个线程之间又是互相独立开来,各自维护的,即我们说的ThreadLocal的作用. 一.概念 可以将每个线程用到的数据与对应的线程号存放到一个map集合中,使用数据时从这个集合中根据线程号获取对应线程的数据,就可以实现线程范围内共享相同的变量. 二.代码 Runnable中的run()方法里面执行Thread.currentThread()都会对应当前Runnable对应的线程,因此A.B中对应的Thread.currentThread

Java高新技术——多线程与并发库(上)

本系列文章旨在分享Java5多线程与并法库的高级应用示例,所用到的大多数类均在java.util.concurrent包下. 传统线程技术回顾 package ustc.lichunchun.thread; /* * 创建线程的两种传统方式 */ public class TraditionalThread { public static void main(String[] args) { //在Thread子类覆盖的run方法中编写运行代码 Thread t1 = new Thread(){

java多线程一览

线程概述: 多线程的目的,不是提高程序的执行速度,而是提高程序的使用率(能抢到CPU的可能比较大). 因为线程是CPU调度的基本单位,所以,当一个程序的线程较多的时候就更容易抢到cpu的资源 进程: 运行中的程序,是系统进行资源分配和调度的独立单位 每个进程都有他自己的内存空间和系统资源 线程: 是进程中的单个顺序控制流,是一条执行路径,是cpu调度的基本单位 一个进程如果有多条执行路径,称:多线程 一个进程如果只有一条执行路径,称:单线程 线程生命周期: java中线程概览: [ ps : 图

跟我学Java多线程——ThreadLocal

ThreadLocal是什么 ThreadLocal这个词如果直接翻译就是"本地线程",可是如果真的按"本地线程"来理解,那就确实大错特错了,ThreadLocal它并不是一个Thread,它跟Thread确实有关系,是用来维护Thread的有关变量的,把它命名为ThreadLocalVariable可能更容易让人理解,在多线程中ThreadLocal为变量在每个线程中都创建了一个跟特定线程有关的变量的副本,这样就可以使每个线程在运行中只可以使用与自己线程有关的特定

Java多线程0:核心理论

并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密,这样才能写出高效.安全.可靠的多线程并发程序.本系列会从线程间协调的方式(wait.notify.notifyAll).Synchronized及Volatile的本质入手,详细解释JDK为我们提供的每种并发工具和底层实现机制.在此基础上,我们会进一步分析java.util.concurrent包的工具类,包括其使用方式.实现源码及其背后的原理.本