java多线程实现数据共享
来源:互联网 发布:mysql大数据统计报表 编辑:程序博客网 时间:2024/06/06 17:42
练习题:卖100个苹果,实现数据共享。
新建一个线程有两种方式:1.继承Thread类;2.是实现Runnable的方式:
那我们就先使用第一种方式来实现:
使用Thread实现数据的共享
第一步:
写一个了ShareThread继承Thread,并在ShareThread定义一个静态的Apple_Counts变量(注意:Apple_Counts因为是静态的,所以是共享数据)
/** * 存在数据共享 * @author liujun * */ class ShareThread extends Thread{ private static int Apple_Counts=100;//共享数据-苹果个数 @Override public void run() { while(Apple_Counts>0){ if (Apple_Counts>0) { try { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
在main方法开始三个线程:
ShareThread mShareThread1=new ShareThread(); ShareThread mShareThread2=new ShareThread(); ShareThread mShareThread3=new ShareThread(); mShareThread1.start(); mShareThread2.start(); mShareThread3.start();
执行的结果:
Thread-0卖了一个苹果,还剩99Thread-1卖了一个苹果,还剩98Thread-2卖了一个苹果,还剩99Thread-0卖了一个苹果,还剩97//这里数据出现有错,因为上面的线程里没有使用同步锁Thread-1卖了一个苹果,还剩97................................................Thread-0卖了一个苹果,还剩2Thread-2卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0Thread-0卖了一个苹果,还剩-1 //这里数据出现有错,因为上面的线程里没有使用同步锁Thread-2卖了一个苹果,还剩-2
第二步:
给ShareThread中添加同步代码块:
/** * 存在数据共享 * @author liujun * */ class ShareThread extends Thread{ private static int Apple_Counts=100;//共享数据-苹果个数 @Override public void run() { while(Apple_Counts>0){ //注意这里添加了同步代码块,同步锁对象是this synchronized (this) { if (Apple_Counts>0) { try { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }
再次执行main方法打印的结果:
Thread-2卖了一个苹果,还剩98Thread-1卖了一个苹果,还剩99Thread-0卖了一个苹果,还剩97Thread-1卖了一个苹果,还剩96Thread-0卖了一个苹果,还剩95................................................Thread-0卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0Thread-2卖了一个苹果,还剩0 //这里数据出现有错,都使用同步锁了?为什么????????Thread-0卖了一个苹果,还剩-1
第三步:
分析代码:
多线程在使用synchronized的时候,多个线程使用的锁对象必须是同一个。
ShareThread mShareThread1=new ShareThread(); ShareThread mShareThread2=new ShareThread(); ShareThread mShareThread3=new ShareThread();
上面这三行代码new了三个对象,那么上面使用的同步锁是this;那上面的多线程在使用synchronized的时候,多个线程使用的锁对象(this)不是同一个,它们是分别为mShareThread1,mShareThread2,mShareThread3。所以上面虽然使用了synchronized还是会出现数据有错。
第四步:
修改代码:
保证使多线程在使用synchronized的时候,多个线程使用的锁对象是同一个就行,下面使用了的同步锁对象是:ShareThread.class。
/** * 存在数据共享 * @author liujun * */ class ShareThread extends Thread{ private static int Apple_Counts=100;//共享数据-苹果个数 @Override public void run() { while(Apple_Counts>0){ //注意这里添加了同步代码块,同步锁对象是ShareThread.class synchronized (ShareThread.class) { if (Apple_Counts>0) { try { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }
再次执行main方法打印的结果正常:
Thread-2卖了一个苹果,还剩98Thread-1卖了一个苹果,还剩99Thread-0卖了一个苹果,还剩97Thread-1卖了一个苹果,还剩96Thread-0卖了一个苹果,还剩95................................................Thread-0卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0
总结:
1.上面通过继承Thread类的方式已经实现数据共享,但是一般我们不定义静态的变量作为数据共享,因为静态的生命周期比较长。
2.建议实现数据共享时使用实现runnable来实现。
使用Runnable实现数据的共享
第一步:
写一个了ShareRunable实现Runnable,并在ShareRunable定义一个Apple_Counts变量(注意:Apple_Counts是共享数据)
/** * 存在数据共享 * @author liujun * */ class ShareRunable implements Runnable{ private int Apple_Counts=100;//Apple_Counts就是共享数据 @Override public void run() { while(Apple_Counts>0){ if(Apple_Counts>0){ try { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
在main方法开始三个线程:
ShareRunable mMyRunables=new ShareRunable(); new Thread(mMyRunables).start(); new Thread(mMyRunables).start(); new Thread(mMyRunables).start();
执行的结果:
Thread-0卖了一个苹果,还剩99Thread-1卖了一个苹果,还剩98Thread-2卖了一个苹果,还剩99................................................Thread-0卖了一个苹果,还剩2Thread-2卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0Thread-0卖了一个苹果,还剩-1 //这里数据出现有错,因为上面的线程里没有使用同步锁Thread-2卖了一个苹果,还剩-2
第二步:
给ShareRunable中添加同步代码块:
/** * 存在数据共享 * @author liujun * */ class ShareRunable implements Runnable{ private int Apple_Counts=100;//Apple_Counts就是共享数据 @Override public void run() { while(Apple_Counts>0){ //注意这里添加了同步代码块,同步锁对象是this或者是ShareThread.class synchronized (this) { if(Apple_Counts>0){ try { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }
再次执行main方法打印的结果正常:
Thread-2卖了一个苹果,还剩99Thread-1卖了一个苹果,还剩98Thread-0卖了一个苹果,还剩97Thread-1卖了一个苹果,还剩96Thread-0卖了一个苹果,还剩95................................................Thread-0卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0
总结:
1.上面通过实现Runable类的方式已经实现数据共享
2.建议实现数据共享时使用实现runnable来实现。
- java多线程实现数据共享
- JAVA多线程共享数据
- Java多线程共享数据
- [java多线程]多线程数据共享
- java 中的多线程 内部类实现 数据共享 和 Runnable实现数据共享
- 简单实现多线程数据共享
- Java---12---多线程练习:卖票---实现数据共享
- JAVA多线程(四)多线程数据共享
- java多线程共享数据和数据并发
- java多线程操作共享数据的安全问题
- Java多线程共享数据、同步、通信
- JAVA多线程的共享数据操作
- Java中多线程之间数据共享
- JAVA多线程的共享数据操作
- java 多线程读取数据注意伪共享
- Java笔记16:多线程共享数据
- java基础多线程之共享数据
- java多线程通信之共享数据
- 第三章 3.5.2 访问数组元素
- iOS开发笔记(三)
- hibernate.hbm2ddl.auto配置浅析
- OpenGL ES 2.0 Shader相关介绍
- C++ Primer | 第一章 开始
- java多线程实现数据共享
- Alluxio(Tachyon) 集群独立运行模式安装遇到的问题(非root用户)
- LA 3514 The Ministers' Major Mess(2-SAT)
- ListView+CheckBox 选中状态错乱问题
- 4.搜索之路——solr部署到Tomcat
- DataReader只读
- CentOS 7.x安装配置
- 5.搜索之路——solr与lucene和nutch关系
- 设计原则——开放封闭原则(Open Close Principle)