iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java如何实现多个线程之间共享数据
  • 556
分享到

Java如何实现多个线程之间共享数据

2024-04-02 19:04:59 556人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录实现多个线程之间共享数据一、 如果每个线程执行的代码相同二、 如果每个线程执行的代码不同多线程之间共享数据的方式探讨方式一:代码一致方式二:代码不一致实现多个线程之间共享数据 一

实现多个线程之间共享数据

一、 如果每个线程执行的代码相同

可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如:卖票系统


class Ticket implements Runnable{  
    private  int tick = 20;  
    Object obj = new Object();    
    public void run(){  
        while(true){  
            synchronized(obj){  
                if(tick>0){  
                    //只能try,因为run是复写了Runnable接口的run,接口的run没有抛  
                    try{Thread.sleep(100);}catch(Exception e){}  //使用sleep不然执行每个线程都会占用完毕
                    System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);  
                }  
            }  
        }  
    }  
}  
  
class  TicketDemo  
{  
    public static void main(String[] args) {  
          
        //只建立了一个Ticket对象,内存中只有一个tick成员变量,所以是共享数据  
        Ticket t = new Ticket();  
  
        Thread t1 = new Thread(t);  
        Thread t2 = new Thread(t);  
        Thread t3 = new Thread(t);  
        Thread t4 = new Thread(t);  
        t1.start();  
        t2.start();  
        t3.start();  
        t4.start();  
    }  
} 

输出结果

Thread-0....sale : 20
Thread-1....sale : 19
 .......
Thread-3....sale : 2
Thread-3....sale : 1

二、 如果每个线程执行的代码不同

1、具体实现

将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。

思想: 一个类提供数据和操作数据的同步方法,另外定义两个线程通过构造函数接收并操作数据,在主函数中直接创建线程对象,即可完成操作(可以实现两个内部类,不用构造方法传值,使用final定义data局部变量)

例如: 设计4个线程,其中两个线程每次对j增加1,另外两个线程每次对j减少1


public class MultyThreadShareMethod1 {        
    public static void main(String[] args){        
        //将数据封装到一个对象上,  
        ShareData2 data1 = new ShareData2();  
          
        //在runnable的构造函数中直接传入去操作  
        for(int i=0;i<2;i++){  
        new Thread(new MyRunnable1(data1)).start();  
        new Thread(new MyRunnable2(data1)).start();  
        }  
    }  
}  
 
//封装共享数据和操作共享数据方法的类  
class ShareData2{  
    private int j = 10;  
    public synchronized void increment() {  
        j++;  
        System.out.println(Thread.currentThread().getName()+" inc : "+j);  
    }  
    public synchronized void decrement() {  
        j--;  
        System.out.println(Thread.currentThread().getName()+" dec : "+j);  
    }  
}  
   
//增加的线程,需要传入一个共享数据  
class MyRunnable1 implements Runnable {       
    private ShareData2 data;  
    public MyRunnable1(ShareData2 data) {  
        this.data = data;  
    }  
    @Override  
    public void run() {  
        for(int i=0;i<10;i++){  
        data.increment();  
        }  
    }  
}  
  
//减少的线程,需要传入一个共享数据  
class MyRunnable2 implements Runnable {   
    private ShareData2 data;  
    public MyRunnable2(ShareData2 data) {  
        this.data = data;  
    }  
    @Override  
    public void run() {  
        for(int i=0;i<10;i++){  
        data.decrement();  
        }  
    }  
}  

输出结果

Thread-0 inc : 11
...
Thread-1 dec : 10

2、 技巧总结

要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法再放在同一个类中,这样比较容易实现它们之间的同步互斥或通信。

极端且简单的方式,即在任意一个类中定义一个static的变量,这将被所有线程共享。

多线程之间共享数据的方式探讨

方式一:代码一致

如果每个线程执行的代码相同,可以用一个 Runnable 对象,这个 Runnable 对象中存放那个共享数据(卖票系统可以这样做)。


public class MultiThreadShareData {
    public static void main(String[] args) {
        MyShareData shareData=new MyShareData();
        //放入不同的线程中
        new Thread(shareData).start(); 
        new Thread(shareData).start(); 
    }
}
 
class MyShareData implements Runnable {
        // 共享的数据
        private int count = 100; 
        @Override
        public void run() {
            while (count > 0) {
                synchronized (this) {
                    if (count > 0) {
                        count--;
                        System.out.println(Thread.currentThread().getName() + " 减了1,count还剩:" + count);
                    } 
                } 
            }
        }
    }

方式二:代码不一致

如果每个线程执行的代码不同时,就需要不同的 Runnable 对象:

a. 将共享数据封装在一个对象中,然后将这个对象逐一传递给各个 Runnable 对象,每个线程对共享数据操作的方法也分配到这个对象中,这样容易实现针对该数据进行的各个操作的互斥通信。


public class MultiThreadShareData { 
    private int shareData=0; 
    public static void main(String[] args) {
        ShareData data = new ShareData(); 
        new Thread(new MyRunnable1(data)).start(); 
        new Thread(new MyRunnable2(data)).start();
    } 
}
 
class MyRunnable1 implements Runnable{ 
    private ShareData data; 
    public MyRunnable1(ShareData data){
        this.data=data;
    }
 
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            //对数据进行增加
            this.data.increment();
        }
    }
}
 
class MyRunnable2 implements Runnable{ 
    private ShareData data; 
    public MyRunnable2(ShareData data){
        this.data=data;
    }
 
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            //对数据进行减少
            this.data.decrement();
        }
    }
}
 

class ShareData{
    //共享数据
    private int j=0; 
    public synchronized void increment(){
        this.j++;
        System.out.println(Thread.currentThread().getName()+":j增加了1后j="+j);
    }
 
    public synchronized void decrement() {
        this.j--;
        System.out.println(Thread.currentThread().getName()+":j减少了1后j="+j);
    }
    public int getJ() {
        return j;
    }
}

b. 将 Runnable 对象作为某一个类的内部类,共享数据作为这个外部类的成员变量,每个线程对共享数据的操作方法也分配到外部类中,实现共享数据的互斥和通信操作,作为内部类的各个 Runnable 对象调用外部类的这些方法。


public class MultiThreadShareData { 
    private int shareData=0; 
    public static void main(String[] args) {
        MultiThreadShareData m=new MultiThreadShareData();
        //初始化Runnable对象
        MyRunnable1 myRunnable1 = m.new MyRunnable1();
        MyRunnable2 myRunnable2=m.new MyRunnable2(); 
        //开启线程
        new Thread(myRunnable1).start(); 
        new Thread(myRunnable2).start();
    }
 
    private synchronized void increment(){
        this.shareData++;
        System.out.println(Thread.currentThread().getName()+":shareData增加了1后shareData="+shareData);
    }
 
    private synchronized void decrement() {
        this.shareData--;
        System.out.println(Thread.currentThread().getName()+":shareData减少了1后shareData="+shareData);
    }
 
    
    class MyRunnable1 implements Runnable{ 
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                increment();
            }
        }
    }
 
    class MyRunnable2 implements Runnable{ 
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                decrement();
            }
        }
    }
}

c. 以上两种方法的组合:将共享数据封装到一个对象中,每个线程对共享数据的操作方法也分配到对象中,对象作为外部类的成员变量或方法中的局部变量,每个线程的 Runnable 作为成员内部类或局部内部类。


 public class MultiThreadShareData {
   public static void main(String[] args) { 
       ShareData data = new ShareData(); 
       new Thread(()->{
           for(int i=0;i<100;i++){
               data.increment();
           }
       }).start();
 
       new Thread(()->{
           for (int j=0;j<100;j++) {
               data.decrement();
           }
       }).start();
   } 
}
 

class ShareData{
   //共享数据
   private int j=0;
 
   
   public synchronized void increment(){
       this.j++;
       System.out.println(Thread.currentThread().getName()+":j增加了1后j="+j);
   }
 
   public synchronized void decrement() {
       this.j--;
       System.out.println(Thread.currentThread().getName()+":j减少了1后j="+j);
   }
 
   public int getJ() {
       return j;
   }
}

总之,要同步互斥的几段代码最好放在几个独立的方法中,这些方法再放入一个类中,这样比较容易实现它们之间的同步互斥和通信。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Java如何实现多个线程之间共享数据

本文链接: https://www.lsjlt.com/news/157180.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java如何实现多个线程之间共享数据
    目录实现多个线程之间共享数据一、 如果每个线程执行的代码相同二、 如果每个线程执行的代码不同多线程之间共享数据的方式探讨方式一:代码一致方式二:代码不一致实现多个线程之间共享数据 一...
    99+
    2024-04-02
  • Java多线程之间如何共享数据
    这篇文章主要介绍Java多线程之间如何共享数据,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、线程范围的共享变量多个业务模块针对同一个static变量的操作 要保证在不同线程中 各模块操作的是自身对应的变量对象pu...
    99+
    2023-06-25
  • Java 多线程之间共享数据
    目录1、线程范围的共享变量2、使用Map实现线程范围内数据的共享3、ThreadLocal实现线程范围内数据的共享4、优化5、实例1、线程范围的共享变量 多个业务模块针对同一个sta...
    99+
    2024-04-02
  • python多线程数据共享怎么实现
    在Python中,可以使用`threading`模块来实现多线程数据共享。具体步骤如下: 导入`threading`模块:`im...
    99+
    2023-10-26
    python
  • C++多线程编程之如何解决多线程数据共享问题
    这篇文章主要讲解了“C++多线程编程之如何解决多线程数据共享问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++多线程编程之如何解决多线程数据共享问题”吧!通过容器创建多个线程#incl...
    99+
    2023-06-15
  • 如何在多个应用之间共享和传输Hadoop数据
    要在多个应用之间共享和传输Hadoop数据,可以使用以下几种方法: 使用Hadoop的HDFS(Hadoop分布式文件系统)来存...
    99+
    2024-02-29
    Hadoop
  • Python 多进程 多线程数据共享
    #!/usr/bin/env python # -*- coding:utf-8 -*- # author: Changhua Gong from multiprocessing import Process, Queue import o...
    99+
    2023-01-31
    多线程 进程 数据
  • 微信小程序如何实现在画面之间共享数据
    这篇文章主要介绍“微信小程序如何实现在画面之间共享数据”,在日常操作中,相信很多人在微信小程序如何实现在画面之间共享数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”微信小程序如何实现在画面之间共享数据”的疑...
    99+
    2023-06-19
  • 使用Java怎么实现线程之间的共享和协作
    这篇文章将为大家详细讲解有关使用Java怎么实现线程之间的共享和协作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一、线程间的共享1.1 ynchronized内置锁用处Java支持多个线程...
    99+
    2023-06-14
  • Java中怎么利用多线程锁实现数据同步共享
    Java中怎么利用多线程锁实现数据同步共享,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。大多数应用程序要求线程互相通信来同步它们的动作。在Java程序中最简单实现同步的方法就是...
    99+
    2023-06-17
  • php如何实现不同域名之间的数据共享
    在当前的Web开发环境中,不同的应用程序运行在不同的域名之下,这就导致了不同域名的应用程序之间无法直接共享数据。在这种情况下,如何实现不同域名之间的数据共享呢?本文将会介绍一种基于PHP的解决方案。一、前端跨域在当前的Web开发环境中,“跨...
    99+
    2023-05-14
    php
  • java多个线程怎么共享一个变量
    Java中多个线程可以通过共享变量来实现线程之间的通信和共享数据。以下是几种常见的实现方式: 使用共享变量作为实例变量:将共享变量...
    99+
    2023-10-27
    java
  • Java线程之间的共享与协作详解
    目录前言一、进程和线程1、进程是程序运行资源分配的最小单位2、线程是CPU 调度的最小单位,必须依赖于进程而存在3、线程无处不在二、CPU 核心数和线程数的关系1、多核心2、多线程3...
    99+
    2024-04-02
  • Java并发编程之线程之间的共享和协作
    目录一、线程间的共享1.1 ynchronized内置锁1.2 volatile关键字1.3 ThreadLocal1.4 Spring的事务借助ThreadLocal类1.4.1 ...
    99+
    2024-04-02
  • java多线程共享全局变量怎么实现
    在Java中,多线程共享全局变量可以通过以下几种方式实现: 使用volatile关键字:将共享变量声明为volatile类型,确...
    99+
    2023-10-23
    java
  • java域对象共享数据如何实现
    这篇“java域对象共享数据如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“java域对象共享数据如何实现”文章吧。域...
    99+
    2023-07-05
  • Java线程之间的共享与协作是什么
    这篇文章主要讲解了“Java线程之间的共享与协作是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java线程之间的共享与协作是什么”吧!一、进程和线程1、进程是程序运行资源分配的最小单位...
    99+
    2023-07-02
  • Vue组件之间的数据共享怎么实现
    本篇内容介绍了“Vue组件之间的数据共享怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、在项目开发中,组件之间的最常见的关系分为如...
    99+
    2023-06-21
  • 【Java】线程数据共享和安全 -ThreadLocal
     🎄欢迎来到@边境矢梦°的csdn博文🎄  🎄本文主要梳理线程数据共享和安全 -ThreadLocal🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做...
    99+
    2023-09-08
    java 开发语言 ThreadLocal servlet tomcat javascript
  • python多线程共享变量怎么实现
    在Python中,可以使用`threading`模块来实现多线程共享变量。 下面是一个简单的例子,展示了如何使用多线程共享变量: i...
    99+
    2023-10-27
    python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作