java 线程间数据共享和android 线程间数据共享异同

来源:互联网 发布:手机相册制作软件 编辑:程序博客网 时间:2024/05/16 14:44

(一)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     @Override17     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             @Override27             public void onClick(View v) {28                 // 新启动一个子线程29                 new Thread(new Runnable() {                    30                     @Override31                     public void run() {32                         // tvMessage.setText("...");33                         // 以上操作会报错,无法再子线程中访问UI组件,UI组件的属性必须在UI线程中访问34                         // 使用post方式修改UI组件tvMessage的Text属性35                         handler.post(new Runnable() {                    36                             @Override37                             public void run() {38                                 tvMessage.setText("使用Handler.post在工作线程中发送一段执行到消息队列中,在主线程中执行。");                        39                             }40                         });                                41                     }42                 }).start();43             }44         });45         46         btnMes2.setOnClickListener(new View.OnClickListener() {47             48             @Override49             public void onClick(View v) {50                 new Thread(new Runnable() {                    51                     @Override52                     public void run() {53                         // 使用postDelayed方式修改UI组件tvMessage的Text属性值54                         // 并且延迟3S执行55                         handler.postDelayed(new Runnable() {56                             57                             @Override58                             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     @Override27     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             @Override41             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         @Override53         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(httpResponse62                             .getEntity());63                     // 得到一个Bitmap对象,并且为了使其在post内部可以访问,必须声明为final64                     final Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);65                     handler.post(new Runnable() {                        66                         @Override67                         public void run() {68                             // 在Post中操作UI组件ImageView69                             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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 跨省离职后社保怎么办 开车到成都限号怎么办 月经量多怎么办吃什么 报驾校体检视力不达标怎么办 换驾驶证c1一只眼不合格怎么办 考驾照紧张腿抖怎么办 驾照该换了色弱怎么办 怀孕5个月感冒咳嗽怎么办 怀孕4个月喉咙痛怎么办 怀孕5个多月总是咳嗽尿失禁怎么办 怀孕7个月感冒了怎么办 怀孕7个月感冒喉咙痛怎么办 孕38周感冒咳嗽喉咙痛怎么办 嗓子痛咳嗽有痰怎么办 怀孕6个月了咳嗽怎么办 怀孕了咳嗽黄痰怎么办 科二5次没考过怎么办 交警开的罚单丢了怎么办 驾驶员从业资格证被水洗了怎么办 驾照考五次没过怎么办 学车每次考不过怎么办 年检超期3个月怎么办 年检超过3个月怎么办 工商执照年检时候忘记密码怎么办 个体工商营业执照年检过期怎么办 忘了审车时间怎么办 汽车年检超过时间了怎么办 星巴克金星会员到期怎么办 驾考学员证丢了怎么办 违章扣满12分怎么办 违章扣满12分后怎么办 东方时尚驾校科二考不过怎么办 东方时尚科二科三考五次没过怎么办 不想考科目三了怎么办 科目三两次没过怎么办 练科目三很紧张怎么办 驾照学员卡丢了怎么办 驾考时考试的车系统出错怎么办 驾驶证超期6个月怎么办 北京汽车年检只有电子保单怎么办 交电费户号9位数怎么办