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之前先初始化线程的消息队列。


package com.bgxt.datatimepickerdemo;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 import android.view.View;
 7 import android.widget.Button;
 8 import android.widget.TextView;
 9 
10 public class HandlerPostActivity1 extends Activity {
11     private Button btnMes1,btnMes2;
12     private TextView tvMessage;
13     // 声明一个Handler对象
14     private static Handler handler=new Handler();
15     
16     @Override
17     protected void onCreate(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(new View.OnClickListener() {
25             
26             @Override
27             public void onClick(View v) {
28                 // 新启动一个子线程
29                 new Thread(new Runnable() {                    
30                     @Override
31                     public void run() {
32                         // tvMessage.setText("...");
33                         // 以上操作会报错,无法再子线程中访问UI组件,UI组件的属性必须在UI线程中访问
34                         // 使用post方式修改UI组件tvMessage的Text属性
35                         handler.post(new Runnable() {                    
36                             @Override
37                             public void run() {
38                                 tvMessage.setText("使用Handler.post在工作线程中发送一段执行到消息队列中,在主线程中执行。");                        
39                             }
40                         });                                
41                     }
42                 }).start();
43             }
44         });
45         
46         btnMes2.setOnClickListener(new View.OnClickListener() {
47             
48             @Override
49             public void onClick(View v) {
50                 new Thread(new Runnable() {                    
51                     @Override
52                     public void run() {
53                         // 使用postDelayed方式修改UI组件tvMessage的Text属性值
54                         // 并且延迟3S执行
55                         handler.postDelayed(new Runnable() {
56                             
57                             @Override
58                             public void run() {
59                                 tvMessage.setText("使用Handler.postDelayed在工作线程中发送一段执行到消息队列中,在主线程中延迟3S执行。");    
60                                 
61                             }
62                         }, 3000);                        
63                     }
64                 }).start();
65                 
66             }
67         });
68     }
69 }

package com.bgxt.datatimepickerdemo;
 2 
 3 import org.apache.http.HttpResponse;
 4 import org.apache.http.client.HttpClient;
 5 import org.apache.http.client.methods.HttpGet;
 6 import org.apache.http.impl.client.DefaultHttpClient;
 7 import org.apache.http.util.EntityUtils;
 8 
 9 import android.app.Activity;
10 import android.app.ProgressDialog;
11 import android.graphics.Bitmap;
12 import android.graphics.BitmapFactory;
13 import android.os.Bundle;
14 import android.os.Handler;
15 import android.view.View;
16 import android.widget.Button;
17 import android.widget.ImageView;
18 
19 public class HandlerPostActivity2 extends Activity {
20     private Button btnDown;
21     private ImageView ivImage;
22     private static String image_path = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
23     private ProgressDialog dialog;
24     // 一个静态的Handler,Handler建议声明为静态的
25     private static  Handler handler=new Handler();
26     @Override
27     protected void onCreate(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(new View.OnClickListener() {            
40             @Override
41             public void onClick(View v) {
42                 // 开启一个子线程,用于下载图片
43                 new Thread(new MyThread()).start();
44                 // 显示对话框
45                 dialog.show();
46             }
47         });
48     }
49     
50     public class MyThread implements Runnable {
51 
52         @Override
53         public void run() {
54             // 下载一个图片
55             HttpClient httpClient = new DefaultHttpClient();
56             HttpGet httpGet = new HttpGet(image_path);
57             HttpResponse httpResponse = null;
58             try {
59                 httpResponse = httpClient.execute(httpGet);
60                 if (httpResponse.getStatusLine().getStatusCode() == 200) {
61                     byte[] data = EntityUtils.toByteArray(httpResponse
62                             .getEntity());
63                     // 得到一个Bitmap对象,并且为了使其在post内部可以访问,必须声明为final
64                     final Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
65                     handler.post(new Runnable() {                        
66                         @Override
67                         public void run() {
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.html
http://www.cnblogs.com/allin/archive/2010/05/19/1738800.html
http://blog.csdn.net/lmj623565791/article/details/38377229






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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值