多线程学习

package com.example.threaddemo;

import org.apache.http.impl.client.TunnelRefusedException;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

	private Button start,stop,pause;
	private TextView time;
	private static boolean  flag=false;
	private int m,s,ms;
	private String show=null;
	private int i=0;
	private String TAG= "ThreadDemo";
	private TimeThread timeThread;
	private int state =1;
	/**
	 * 在非UI线程中不能处理UI
	 * 借助Handler机制来更新时间的变化
	 * 
	 * 1.子线程借助主线程中的handler,调用handler.sendMessage(msg)方法向主线程发送消息
	 * 2.这消息会被主线程放到消息队列里面
	 * 3.主线程的looper发现消息队列里面有消息,会调用消息处理者的handleMessage方法处理消息
	 * 4.在handleMessage方法中处理UI
	 */
	private Handler handler =new Handler()
	{
		public void handleMessage(android.os.Message msg) 
		{
			if(msg.what==1)
			{
				time.setText(show);
			}
			else if(msg.what==2)
			{
				time.setText("00:00:00");
			}
		};
	};
	
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		m=0;
		s=0;
		ms=0;
		initView();
		
		/**
		 * 这样实际上还是运行在主线程中
		 * 因为初始化的时候是获取的主线程的looper
		 * Handler handler2 =new Handler();相当于
		 * Handler handler2 =new Handler(getMainLooper());
		 * 所以这种情况下还是可以更新UI的
		 */
	    Handler handler2 =new Handler(getMainLooper());
		handler2.post(new Runnable() {			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				time.setText("当前线程:"+Thread.currentThread().getName());
				//这里打印的是main 主线程
			}
		});
	}

	private void  initView()
	{
		start = (Button) findViewById(R.id.start);
		stop = (Button) findViewById(R.id.stop);
		pause = (Button) findViewById(R.id.pause);
		time = (TextView) findViewById(R.id.time);
		
		start.setOnClickListener(this);
		stop.setOnClickListener(this);
		stop.setClickable(false);
		pause.setOnClickListener(this);
		pause.setClickable(false);
	}
	@Override
	public void onClick(View v) 
	{
		// TODO Auto-generated method stub
		int id = v.getId();
		switch(id)
		{
			case R.id.start:
				flag=true;	
				timeThread=new TimeThread(""+(i++));
				timeThread.start();
				
				state=3;
				start.setClickable(false);
				pause.setClickable(true);
				stop.setClickable(true);
				break;
			case R.id.stop:
				flag=false;
				m=s=ms=0;
				state=1;
				Message msg =new Message();
				msg.what=2;
				handler.sendMessage(msg);
				start.setClickable(true);
				pause.setClickable(false);
				stop.setClickable(true);
				break;
			case R.id.pause:
				flag=false;
				state=2;
				start.setClickable(true);
				pause.setClickable(true);
				stop.setClickable(true);
				break;
		}
	}
	
	/**
	 * 扩展java.lang.Thread类
	 * 在onClick中调用TimeThread的start方法,线程也就启动了,这样,整个应用就在多线程下运行。
	 * 注意:start()方法的调用后并不是立即执行多线程代码,而是使得该线
	 * 程变为可运行态(Runnable),什么时候运行是由操作系统决定的。
	 * 多线程程序是乱序执行。因此,只有乱序执行的代码才有必要设计为多线程。
	 * Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,
	 * 以留出一定时间给其他线程执行的机会。实际上所有的多线程代码执行顺序都是不确定的,每次执行的结果都是随机的。
	 * @author tang
	 *
	 */
	class TimeThread extends Thread
	{
		public TimeThread(String name)
		{
			super(name);
		}
		@Override
		public void run() 
		{
			Log.i(TAG, getName());
			// TODO Auto-generated method stub
			try {
				while(flag)
				{
					Thread.sleep(10);
					ms+=1;
					if(ms == 100)
					{
						ms=0;
						s+=1;
						if(s==60)
						{
							s=0;
							m+=1;
						}
					}
					Message msg =new Message();
					msg.what=1;
					handler.sendMessage(msg);
					show = m+":"+s+":"+ms;
				}
				if(!flag)
				{
					if(state ==1)
					{
						Message msg =new Message();
						msg.what=2;
						handler.sendMessage(msg);
					}
				}
				i=0;
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}
/**
 * 通过实现Runnable接口,使得该类有了多线程类的特征。
 * run()方法是多线程程序的一个约定。所有的多线程代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类。
 * 在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 
 * 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。
 * 实际上所有的多线程代码都是通过运行Thread的start()方法来运行的。
 * 因此,不管是扩展Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的
 */
//	class TimeRunnable implements Runnable
//	{
//		@Override
//		public void run() {
//			// TODO Auto-generated method stub
//			// do something you need
//		}
//	}
//	TimeRunnable runnable =new TimeRunnable();
//	Thread thread =new Thread(runnable);
//	thread.start();
//	
//	其实android更习惯于这样写:
//	new Thread(new Runnable() {
//		@Override
//		public void run() {
//			// TODO Auto-generated method stub
//			// do something you need
//		}
//	}).start(); 
	
	
	
//Thread类一些API
//	void setPriority(int newPriority) 
//	 更改线程的优先级。 
//	void interrupt() 
//	 中断线程。 
//	static boolean interrupted() 
//	 测试当前线程是否已经中断。 
//	boolean isAlive() 
//	 测试线程是否处于活动状态。 
//	boolean isDaemon() 
//	 测试该线程是否为守护线程。 
//	boolean isInterrupted() 
//	 测试线程是否已经中断。 
//	void join() 
//	 等待该线程终止。 
//	void join(long millis) 
//	 等待该线程终止的时间最长为 millis 毫秒。 
//	void join(long millis, int nanos) 
//	 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
//	long getId() 
//	 返回该线程的标识符。 
//	String getName() 
//	 返回该线程的名称。 
//	int getPriority() 
//	 返回线程的优先级。 
//	Thread.State getState() 
//	 返回该线程的状态。 
//	static void sleep(long millis) 
//	 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。 
//	static void sleep(long millis, int nanos) 
//	 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)。 
//	void start() 
//	 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。 
//	void stop() 
//	void stop(Throwable obj) 
//	已过时。 该方法具有固有的不安全性。
//	用 Thread.stop 来终止线程将释放它已经锁定的所有监视器
//	(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。
//	如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,
//	这有可能导致任意的行为。
//	void suspend() 
//	 已过时。 该方法已经遭到反对,因为它具有固有的死锁倾向。
//	 如果目标线程挂起时在保护关键系统资源的监视器上保持有锁,
//	 则在目标线程重新开始以前任何线程都不能访问 该资源。
//	 如果重新开始目标线程的线程想在调用 resume 之前锁定该监视器,则会发生死锁。
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值