android多线程访问共享数据,java 线程间数据共享和android 线程间数据共享异同

(一)Java多线程编程访问共享对象和数据的方法

1、每个线程执行的代码相同,例如,卖票:多个窗口同时卖这100张票,这100张票需要多个线程共享。

2、每个线程执行的代码不同,例如:设计四个线程,其中两个线程每次对j增加1,另外两个线程每次对j减少1。

a、如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个对象中有共享数据。卖票就可以这样做,每个窗口都在做卖票任务,卖的票都是同一个数据(点击查看具体案例)。

b、如果每个线程执行的代码不同,就需要使用不同的Runnable对象,有两种方式实现Runnable对象之间的数据共享:

1)、将共享数据单独封装到一个对象中,同时在对象中提供操作这些共享数据的方法,可以方便实现对共享数据各项操作的互斥和通信。

2、)将各个Runnable对象作为某个类的内部类,共享数据作为外部类的成员变量,对共享数据的操作方法也在外部类中提供,以便实现互斥和通信,内部类的Runnable对象调用外部类中操作共享数据的方法即可

demon :

package com.ljq.test.thread;

/**

* 多个线程之间共享数据的方式

*

* 设计四个线程,其中两个线程每次对j增加1,另外两个线程每次对j减少1。循环100次。

*

* @author xuhong.tian

*

*/

public class MultiThreadShareDataDemon {

public static void main(String[] args) {

ShareData data2 = new ShareData();

new Thread(new DecrementRunnable(data2)).start();

new Thread(new IncrementRunnable(data2)).start();

final ShareData data1 = new ShareData();

new Thread(new Runnable() {

@Override

public void run() {

data1.decrement();

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

data1.increment();

}

}).start();

}

}

/**

* 创建线程类,负责对j减少1

*

* @author Administrator

*

*/

class DecrementRunnable implements Runnable {

private ShareData data;

public DecrementRunnable(ShareData data) {

this.data = data;

}

public void run() {

for (int i = 0; i < 100; i++) {

data.decrement();

}

}

}

/**

* 创建线程类,负责对j增加1

*

* @author Administrator

*

*/

class IncrementRunnable implements Runnable {

private ShareData data;

public IncrementRunnable(ShareData data) {

this.data = data;

}

public void run() {

for (int i = 0; i < 100; i++) {

data.increment();

}

}

}

/**

* 封装共享数据

*

* @author Administrator

*

*/

class ShareData {

private int count = 0;

/**

* 每次对j增加1

*/

public synchronized void increment() {

count++;

System.out.println("j++=" + count);

}

/**

* 每次对j减少1

*/

public synchronized void decrement() {

count--;

System.out.println("j--=" + count);

}

}

(二)andriod 线程间通信和数据共享

在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个是android的新概念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handler,我们有消息循环,就要往消息循环里面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,把这些都封装在Handler里面,注意Handler只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。

但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。

一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列。

packagecom.bgxt.datatimepickerdemo;23 importandroid.app.Activity;4 importandroid.os.Bundle;5 importandroid.os.Handler;6 importandroid.view.View;7 importandroid.widget.Button;8 importandroid.widget.TextView;9

10 public class HandlerPostActivity1 extendsActivity {11 privateButton btnMes1,btnMes2;12 privateTextView tvMessage;13 //声明一个Handler对象

14 private static Handler handler=newHandler();15

16 @Override17 protected voidonCreate(Bundle savedInstanceState) {18 super.onCreate(savedInstanceState);19 setContentView(R.layout.message_activity);20

21 btnMes1=(Button)findViewById(R.id.btnMes1);22 btnMes2=(Button)findViewById(R.id.btnMes2);23 tvMessage=(TextView)findViewById(R.id.tvMessage);24 btnMes1.setOnClickListener(newView.OnClickListener() {25

26 @Override27 public voidonClick(View v) {28 //新启动一个子线程

29 new Thread(newRunnable() {30 @Override31 public voidrun() {32 //tvMessage.setText("...");33 //以上操作会报错,无法再子线程中访问UI组件,UI组件的属性必须在UI线程中访问34 //使用post方式修改UI组件tvMessage的Text属性

35 handler.post(newRunnable() {36 @Override37 public voidrun() {38 tvMessage.setText("使用Handler.post在工作线程中发送一段执行到消息队列中,在主线程中执行。");39 }40 });41 }42 }).start();43 }44 });45

46 btnMes2.setOnClickListener(newView.OnClickListener() {47

48 @Override49 public voidonClick(View v) {50 new Thread(newRunnable() {51 @Override52 public voidrun() {53 //使用postDelayed方式修改UI组件tvMessage的Text属性值54 //并且延迟3S执行

55 handler.postDelayed(newRunnable() {56

57 @Override58 public voidrun() {59 tvMessage.setText("使用Handler.postDelayed在工作线程中发送一段执行到消息队列中,在主线程中延迟3S执行。");60

61 }62 }, 3000);63 }64 }).start();65

66 }67 });68 }69 }packagecom.bgxt.datatimepickerdemo;23 importorg.apache.http.HttpResponse;4 importorg.apache.http.client.HttpClient;5 importorg.apache.http.client.methods.HttpGet;6 importorg.apache.http.impl.client.DefaultHttpClient;7 importorg.apache.http.util.EntityUtils;8

9 importandroid.app.Activity;10 importandroid.app.ProgressDialog;11 importandroid.graphics.Bitmap;12 importandroid.graphics.BitmapFactory;13 importandroid.os.Bundle;14 importandroid.os.Handler;15 importandroid.view.View;16 importandroid.widget.Button;17 importandroid.widget.ImageView;18

19 public class HandlerPostActivity2 extendsActivity {20 privateButton btnDown;21 privateImageView ivImage;22 private static String image_path = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";23 privateProgressDialog dialog;24 //一个静态的Handler,Handler建议声明为静态的

25 private static Handler handler=newHandler();26 @Override27 protected voidonCreate(Bundle savedInstanceState) {28 super.onCreate(savedInstanceState);29 setContentView(R.layout.asynctask_activity);30

31 btnDown =(Button) findViewById(R.id.btnDown);32 ivImage =(ImageView) findViewById(R.id.ivSinaImage);33

34 dialog = new ProgressDialog(this);35 dialog.setTitle("提示");36 dialog.setMessage("正在下载,请稍后...");37 dialog.setCancelable(false);38

39 btnDown.setOnClickListener(newView.OnClickListener() {40 @Override41 public voidonClick(View v) {42 //开启一个子线程,用于下载图片

43 new Thread(newMyThread()).start();44 //显示对话框

45 dialog.show();46 }47 });48 }49

50 public class MyThread implementsRunnable {51

52 @Override53 public voidrun() {54 //下载一个图片

55 HttpClient httpClient = newDefaultHttpClient();56 HttpGet httpGet = newHttpGet(image_path);57 HttpResponse httpResponse = null;58 try{59 httpResponse =httpClient.execute(httpGet);60 if (httpResponse.getStatusLine().getStatusCode() == 200) {61 byte[] data =EntityUtils.toByteArray(httpResponse62 .getEntity());63 //得到一个Bitmap对象,并且为了使其在post内部可以访问,必须声明为final

64 final Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);65 handler.post(newRunnable() {66 @Override67 public voidrun() {68 //在Post中操作UI组件ImageView

69 ivImage.setImageBitmap(bmp);70 }71 });72 //隐藏对话框

73 dialog.dismiss();74 }75 } catch(Exception e) {76 e.printStackTrace();77 }78 }79

80 }81 }http://www.cnblogs.com/jackhuclan/archive/2013/07/10/3182084.htmlhttp://www.cnblogs.com/allin/archive/2010/05/19/1738800.htmlhttp://blog.csdn.net/lmj623565791/article/details/38377229

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值