线程同步问题

============问题描述============

我想让下面的mythread中的循环执行完毕之后再在主线程里给messageList设置Adapter。

Thread myThread = new Thread(new Runnable() {

			@Override

			public void run() {

				try {

					Map<String, String> map1 = new HashMap<String, String>();

					map1.put("", "");

					String retStr = "";

					retStr = NetTool.sendGetRequest(messageShowUrl, map1,

							"utf-8");

					String[] str = retStr.split(",");

					list = Arrays.asList(str);

					listAll.clear();

					for (int i = 0; i < str.length / 5; i++) {

						Map<String, Object> map2 = new HashMap<String, Object>();

						map2.put("user_name", list.get(i * 5));

						map2.put("object_words", list.get(i * 5 + 1));

						map2.put("my_words", list.get(i * 5 + 2));

						map2.put("date", list.get(i * 5 + 4));

						// 如果用户没有传照片,map2中传的imageUrl就为空

						System.out.println("list3 = " + list.get(i * 5 + 3));

						if (!list.get(i * 5 + 3).equals(" ")) {

							String imageUrl1 = "http://10.0.2.2:8080/BBStuServlet/"

									+ list.get(i * 5 + 3);

							String imageUrl = imageUrl1.replace(" ", "");

							map2.put("imageUrl", imageUrl);

						} else {

							map2.put("imageUrl", "");

						}

						listAll.add(map2);

					}

				} catch (Exception e) {

					e.printStackTrace();

				}

			}

		});

		myThread.start();

		MyAdapter adapter = new MyAdapter(this);

		messageList.setAdapter(adapter);

于是我改成了下面的形式:

Thread myThread = new Thread(new Runnable() {

			@Override

			public void run() {

				try {

					Map<String, String> map1 = new HashMap<String, String>();

					map1.put("", "");

					String retStr = "";

					retStr = NetTool.sendGetRequest(messageShowUrl, map1,

							"utf-8");

					String[] str = retStr.split(",");

					list = Arrays.asList(str);

					listAll.clear();

					synchronized (this) {

						for (int i = 0; i < str.length / 5; i++) {

							Map<String, Object> map2 = new HashMap<String, Object>();

							map2.put("user_name", list.get(i * 5));

							map2.put("object_words", list.get(i * 5 + 1));

							map2.put("my_words", list.get(i * 5 + 2));

							map2.put("date", list.get(i * 5 + 4));

							// 如果用户没有传照片,map2中传的imageUrl就为空

							System.out.println("list3 = " + list.get(i * 5 + 3));

							if (!list.get(i * 5 + 3).equals(" ")) {

								String imageUrl1 = "http://10.0.2.2:8080/BBStuServlet/"

										+ list.get(i * 5 + 3);

								String imageUrl = imageUrl1.replace(" ", "");

								map2.put("imageUrl", imageUrl);

							} else {

								map2.put("imageUrl", "");

							}

							listAll.add(map2);

						}

						notifyAll();

					}

				} catch (Exception e) {

					e.printStackTrace();

				}

			}

		});

		myThread.start();

		synchronized (myThread) {

			try {

				myThread.wait();

				MyAdapter adapter = new MyAdapter(this);

				messageList.setAdapter(adapter);

			} catch (InterruptedException e) {

				// TODO Auto-generated catch block

				e.printStackTrace();

			}

		}

但是运行的时候直接就黑屏没有响应了,请问这是怎么回事?到底是哪里不对

============解决方案1============

你这里 myThread.wait();了,是在主线程里wait了啊,在等着线程里的notifyAll呢,当然会黑掉

你应该用handler来发消息

============解决方案2============

楼主,1楼的说法是正确的,这里我把你的代码整理了下  ,红色字体为关键处

package app.example.testapp;

import java.util.Arrays;

import java.util.HashMap;

import java.util.Map;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.app.Activity;

import android.view.Menu;

public class MainActivity extends Activity {

Thread myThread = new Thread(new Runnable() {

@Override

public void run() {

try {

Map<String, String> map1 = new HashMap<String, String>();

map1.put("", "");

String retStr = "";

retStr = NetTool.sendGetRequest(messageShowUrl, map1,

"utf-8");

String[] str = retStr.split(",");

list = Arrays.asList(str);

listAll.clear();

for (int i = 0; i < str.length / 5; i++) {

Map<String, Object> map2 = new HashMap<String, Object>();

map2.put("user_name", list.get(i * 5));

map2.put("object_words", list.get(i * 5 + 1));

map2.put("my_words", list.get(i * 5 + 2));

map2.put("date", list.get(i * 5 + 4));

// 如果用户没有传照片,map2中传的imageUrl就为空

System.out.println("list3 = " + list.get(i * 5 + 3));

if (!list.get(i * 5 + 3).equals(" ")) {

String imageUrl1 = "http://10.0.2.2:8080/BBStuServlet/"

+ list.get(i * 5 + 3);

String imageUrl = imageUrl1.replace(" ", "");

map2.put("imageUrl", imageUrl);

} else {

map2.put("imageUrl", "");

}

listAll.add(map2);

}

handler.sendEmptyMessage(0);//给Handler发送消息

} catch (Exception e) {

e.printStackTrace();

}

}

});

Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

if (msg.what==0) {//接收到对应的消息进行处理

MyAdapter adapter = new MyAdapter(this);

messageList.setAdapter(adapter);

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

myThread.start();// 开启线程

}

}

时间: 2024-08-14 07:20:41

线程同步问题的相关文章

[.net]基元线程同步构造

1 /* 基元线程同步构造 2 用户模式构造: 3 易变构造(Volatile Construct) 4 互锁构造(Interlocked Construct):自旋锁(Spinlock) 乐观锁(Optimistic Concurrency Control,乐观并发控制) 5 内核模式构造: 6 事件构造(Event) 7 信号量构造(Semaphore) 8 互斥体构造(Mutex) 9 */ 10 11 //易变构造,Volatile.Write()之前的所有字段写入操作,必须再该方法调用

iOS多线程编程:线程同步总结 NSCondtion

1:原子操作 - OSAtomic系列函数 iOS平台下的原子操作函数都以OSAtomic开头,使用时需要包含头文件<libkern/OSBase.h>.不同线程如果通过原子操作函数对同一变量进行操作,可以保证一个线程的操作不会影响到其他线程内对此变量的操作,因为这些操作都是原子式的.因为原子操作只能对内置类型进行操作,所以原子操作能够同步的线程只能位于同一个进程的地址空间内. 2:锁 - NSLock系列对象 iOS平台下的锁对象为NSLock对象,进入锁通过调用lock函数,解锁调用unl

线程同步之EVENT

事件可传信给其他线程,表示某些条件现在已具备,比如有可用的消息. 事件可分为手动复位和自动复位,前者可传信给许多同时等待事件的线程而且可以被复位. 自动复位的事件传信给单个等待时间的线程,该事件会自动复位. Applications can use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O

【java并发】(2) Java线程同步:synchronized锁住的是代码还是对象

在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在方法上. 关键是,不要认为给方法或者代码段加上synchronized就万事大吉,看下面一段代码: class Sync { public synchronized void test() { System.out.println("test开始.."); try { Thread.sle

Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)

一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会引起此共享资源的不一致性.因此,为避免线程安全问题,应该避免多线程环境下对此共享资源的并发访问. 线程安全问题多是由全局变量和静态变量引起的,当多个线程对共享数据只执行读操作,不执行写操作时,一般是线程安全的:当多个线程都执行写操作时,需要考虑线程同步来解决线程安全问题. 二.线程同步(synchr

系统API函数实现多线程及线程同步

1.线程的创建 须包含头文件:#include <windows.h> HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); lpThreadAttributes:指向SECURI

Java进击C#——语法之线程同步

上一章我们讲到关于C#线程方向的应用.但是笔者并没有讲到多线程中的另一个知识点--同步.多线程的应用开发都有可能发生脏数据.同步的功能或多或少都会用到.本章就要来讲一下关于线程同步的问题.根据笔者这几年来的.NET开发可以了解到的同步方式至少有四种以上.如.lock.volatile.Monitor等. lock方式 对lock的关键字作用跟JAVA的synchronized关键字类似.但有一定的差别.JAVA的synchronized关键字可能修饰在方法上面.可惜C#却不能修饰在方法上面.用法

经典线程同步 信号量Semaphore

阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event> <秒杀多线程第七篇经典线程同步互斥量Mutex> 前面介绍了关键段CS.事件Event.互斥量Mutex在经典线程同步问题中的使用.本篇介绍用信号量Semaphore来解决这个问题. 首先也来看看如何使用信号量,信号量Semaphore常用有三个函数,使用很方便.下面是这几个函数的原型和使

Linux系统开发9 线程同步

[本文谢绝转载原文来自http://990487026.blog.51cto.com] <大纲> Linux系统编程8 线程同步 多线程共享资源,不加锁,同步互斥演示 多线程共享资源,加锁,同步互斥演示 读写锁:3个写线程,5个读线程,不加锁,并行处理 读写锁:3个写线程,5个读线程,加读写锁,串行处理 条件变量:生产消费者模型 信号量 进程间锁 文件锁: 习题 死锁,哲学家就餐 多线程共享资源,不加锁,同步互斥演示 [email protected]:~/linux_c/thread$ ca

线程同步方式比较

用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区. 内核模式下的方法有:事件,信号量,互斥量. 临界区 保证在某一时刻只有一个线程能访问数据的简便办法.在任意时刻只允许一个线程对共享资源进行访问.如果有多个线程试图同时访问临界区,那么 在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开.临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操 作共享资源的目的. 仅能在同一进程内使用 互斥量 Mutex 互斥量跟临界区很相似,只有拥有互