(一)Java多线程编程访问共享对象和数据的方法
1、每个线程执行的代码相同,例如,卖票:多个窗口同时卖这100张票,这100张票需要多个线程共享。
2、每个线程执行的代码不同,例如:设计四个线程,其中两个线程每次对j增加1,另外两个线程每次对j减少1。
a、如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个对象中有共享数据。卖票就可以这样做,每个窗口都在做卖票任务,卖的票都是同一个数据(点击查看具体案例)。
b、如果每个线程执行的代码不同,就需要使用不同的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