線程範圍的共享數據包括線程範圍內共享和線程間共享數據
- 線程範圍內共享數據
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(){
@Override
public 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() {
@Override
public 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;
}
}
- 線程之間共享數據
// 設計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();
}
}
}