多线程共享数据
来源:互联网 发布:php记账系统源码 编辑:程序博客网 时间:2024/06/05 15:08
线程范围的共享数据包括线程范围内共享和线程间共享数据
- 线程范围内共享数据
线程范围内共享数据有两种方式:自定义一个Map<Thread, Object>用来保存线程的数据或者是用ThreadLocal类。
使用Map<Thread, Object>
package traditional;import java.util.HashMap;import java.util.Map;import java.util.Random;public class ThreadScopeShareData {private static Map<Thread,Integer> threadMap = new HashMap<Thread,Integer>();public static void main(String[] args) {for(int i = 0 ; i < 2; i++){//开启两个线程new Thread(new Runnable(){@Overridepublic void run() {int data = new Random().nextInt();System.out.println(Thread.currentThread().getName()+" has put data : "+data);threadMap.put(Thread.currentThread(), data);new A().get();new B().get();}}).start();}}static class A{public void get(){int data = threadMap.get(Thread.currentThread());System.out.println("A from "+ Thread.currentThread().getName()+"has put data : "+ data);}}static class B{public void get(){int data = threadMap.get(Thread.currentThread());System.out.println("B from "+ Thread.currentThread().getName()+"has put data : "+ data);}}}
使用ThreadLocal类
package traditional;import java.util.Random;/** * ThreadLocal实现线程范围的共享变量 */public class ThreadLocalTest {private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();// private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();//不要这样做public static void main(String[] args) {for (int i = 0; i < 2; i++) {// 开启两个线程new Thread(new Runnable() {@Overridepublic void run() {int data = new Random().nextInt();System.out.println(Thread.currentThread().getName() + " has put data : " + data);threadLocal.set(data);// 把data数据存储到当前线程/* * MyThreadScopeData myData = new MyThreadScopeData(); * myData.setName("name"+data); myData.setAge(data); * myThreadScopeData.set(myData); */MyThreadScopeData.getThreadInstance().setName("name" + data);MyThreadScopeData.getThreadInstance().setAge(data);new A().get();new B().get();}}).start();}}static class A {public void get() {int data = threadLocal.get();// 取到当前线程的data值System.out.println("A from " + Thread.currentThread().getName() + " has put data : " + data);MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();System.out.println("A from " + Thread.currentThread().getName() + " get myData : " + myData.getName() + ", "+ myData.getAge());}}static class B {public void get() {int data = threadLocal.get();// 取到当前线程的data值System.out.println("B from " + Thread.currentThread().getName() + " has put data : " + data);MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();System.out.println("B from " + Thread.currentThread().getName() + " get myData : " + myData.getName() + ", "+ myData.getAge());}}}/** * 把ThreadLocal放到封装的类中 * * 专门与线程绑定 在线程的任何地方调用该类的instance,就会产生与当前线程有关的实例 * */class MyThreadScopeData {// 类似于单例设计模式private MyThreadScopeData() {}public /* synchronized */ static MyThreadScopeData getThreadInstance() {MyThreadScopeData instance = map.get();if (instance == null) {instance = new MyThreadScopeData();map.set(instance);}return instance;}// private static MyThreadScopeData instance = null;private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
- 线程之间共享数据
1、如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如买票系统就可以这么做。
2、如果每个线程执行的代码不相同,这时候就需要用不同的Runnable对象
2.1、把共享变量封装在一个对象中,然后把这个对象逐一传递给各个Runnable对象。(可以写自己的Runnable,然后以构造函数的方式传递共享变量进去)
// 设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。package traditional; public class MultiThreadShareData { public static void main(String[] args) { final ShareData1 data1 = new ShareData1(); new Thread(new Runnable(){ @Override public void run() { data1.decrement(); } }).start(); new Thread(new Runnable(){ @Override public void run() { data1.increment(); } }).start(); } }class ShareData1{ private int j = 0; public synchronized void increment(){ j++; } public synchronized void decrement(){ j--; } } 内部类可以访问外部类的成员变量另外的方法:package traditional; public class ThreadTest1 { private int j; public static void main(String args[]) { ThreadTest1 tt = new ThreadTest1(); Inc inc = tt.new Inc(); Dec dec = tt.new Dec(); for (int i = 0; i < 2; i++) { Thread t = new Thread(inc); t.start(); t = new Thread(dec); t.start(); } } private synchronized void inc() { j++; System.out.println(Thread.currentThread().getName() + "-inc:" + j); } private synchronized void dec() { j--; System.out.println(Thread.currentThread().getName() + "-dec:" + j); } class Inc implements Runnable { public void run() { for (int i = 0; i < 100; i++) { inc(); } } } class Dec implements Runnable { public void run() { for (int i = 0; i < 100; i++) { dec(); } } }
阅读全文
0 0
- C#多线程共享数据
- C#多线程共享数据
- C#多线程共享数据
- perl 多线程共享数据
- 多线程共享数据
- 多线程共享数据案例
- 多线程中的数据共享
- 多线程五共享数据
- C#多线程共享数据
- 多线程数据共享
- 多线程数据共享
- 多线程数据共享
- 多线程数据共享分析
- 多线程共享数据
- 多线程---数据共享
- JAVA多线程共享数据
- 多线程共享数据
- Java多线程共享数据
- 简单理解Socket及TCP/IP、Http、Socket的区别
- java.lang.IllegalArgumentException: Illegal character in query at index
- 从执行角度解释:return与finally执行顺序
- map用法
- C++抽象编程——指针(3)——指针运算
- 多线程共享数据
- 在C#中调用EVAL函数方法,通过字符串计算
- ubuntu14.04英文环境下安装中文输入法
- 基础数学
- 利用xinetd进行时间同步
- 数组名和取地址数组名的区别
- lakeshore自学笔记(一)
- Bootstrap 中的 aria-label 和 aria-labelledby
- Android初学——开机宣传界面