Android 多线程学习

目录

1. 什么是进程,什么是线程,两者有何区别

2. 线程生命周期

2.1 Android 主线程与子线程概念理解

3. Java 多线程实例Demo

3.1 继承Thread

3.2 实现Runnable接口

4. Android 多线程实现

4.1 Handler实现

4.2 HandlerThread实现

4.3 AsyncTask实现

4.4 IntentService实现Demo


1. 什么是进程,什么是线程,两者有何区别

答:进程是cpu资源分配的最小单位。线程是cpu执行调度的最小单位。进程之间不能共享资源,而线程共享所在进程的地址空间和其它资源;一个进程内可拥有多个线程,进程可开启进程,也可开启线程;一个线程只能属于一个进程,线程可直接使用同进程的资源,线程依赖于进程而存在。

详细的说明转自 aaronthon博客,内容见下?

什么是进程?什么是线程?

进程是系统中正在运行的一个程序,程序一旦运行就是进程。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。

一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间。线程与进程的一个主要区别是,统一进程内的一个主要区别是,同一进程内的多个线程会共享部分状态,多个线程可以读写同一块内存(一个进程无法直接访问另一进程的内存)。同时,每个线程还拥有自己的寄存器和栈,其他线程可以读写这些栈内存。

线程是进程的一个实体,是进程的一条执行路径。当一个线程修改了进程的资源,它的兄弟线程可以立即看到这种变化。

进程和线程的区别体现在以下几个方面:

1.地址空间和其他资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其他进程内不可见。

2.通信:进程间通信IPC(管道,信号量,共享内存,消息队列),线程间可以直接独写进程数据段(如全局变量)来进程通信—— 需要进程同步和互斥手段的辅助,以保证数据的一致性。

3.调度和切换:线程上下文切换比进程上下文切换快得多。

4.在多线程OS中,进程不是一个可执行的实体。

进程和线程的选择取决以下几点:

1.需要频繁创建销毁的优先使用线程;因为对进程来说创建和销毁一个进程的代价是很大的。

2.线程的切换速度快,所以在需要大量计算,切换频繁时使用线程,还有耗时的操作时用使用线程可提高应用程序的响应。

3.因为对CPU系统的效率使用上线程更占优势,所以可能要发展到多机分布的用进程,多核分布用线程。

4.并行操作时用线程,如C/S架构的服务器端并发线程响应用户的请求。

5.需要更稳定安全时,适合选择进程;需要速度时,选择线程更好。

2. 线程生命周期

  • 新建状态 New status : 创建Thread类的对象且还未调用start()方法,线程进入新建状态,这时不认为这线程是活动的状态
  • 就绪状态 Runnable status : 线程进入就绪状态的几种方式:1. 线程在新建状态中调用start()方法进入就绪状态;2. 线程在运行状态失去CPU资源从而回到就绪状态;3.  线程从阻塞或等待状态上回到就绪状态。处于就绪状态的线程是活动的线程。
  • 运行状态 Running status : 线程在就绪状态上获得CPU资源,执行run()。
  • 阻塞状态/等待状态 Blocked/Waiting status : 处于运行状态的线程通过调用sleep() | wait() | Input/Output请求 | 同步锁状态 进入阻塞/等待状态。
  • 死亡状态 Dead status : 当线程成功的执行完run()方法后进入死亡状态,这时线程不是活的,所以这时你调用start()方法就会跳java.lang.IllegalThreadStateException异常

2.1 Android 主线程与子线程概念理解

在 Android 中,一个进程默认只有一个线程,这个就是我们的主线程,主要负责处理 UI 的工作,以及通过 UI 界面与用户进行交互,所以当主线程卡顿的时候,就会呈现给用户界面卡顿的情况,从而用户觉得 APP 反应迟钝很“卡”。所以为了防止出现这种情况,我们开发者应该保证主线程在任何时候都保持着较高的响应速度,即主线程不能做任何耗时的操作(如:网络请求、I/0操作、数据库读写等),这些耗时的操作需要新建一个线程,即子线程(也叫工作线程)中去处理。

3. Java 多线程实例Demo

Java实现多线程的方法,创建线程类的方法有两种:一继承Thread类来,二实现Runnable接口。

3.1 继承Thread

public class MyThread extends Thread {
	public void run() {
		System.out.println("MyThread run..");
	}
}

public class ThreadTest {
	public static void main(String[] args) {
		MyThread thread = new MyThread();
		thread.start();
	}
}

3.2 实现Runnable接口

public class MyRunnable implements Runnable{
	@Override
	public void run() {
		//放业务逻辑
		System.out.println("MyRunnable run..,");
	}
}

public class MyRunnableTest {
	public static void main(String[] args) {
		Runnable runnable = new MyRunnable();
		Thread thread = new Thread(runnable);
		thread.start();
	}
}

4. Android 多线程实现

子线程不可处理 UI 工作, 任何 UI 工作都需在主线程上处理。

4.1 Handler实现

利用Handler来实现子线程更新UI工作,

具体代码见下:

public class HandlerAddThread extends AppCompatActivity {
    private TextView mDisplayTv;
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_add_thread);

        Button mClickBtn = findViewById(R.id.click_btn);
        mDisplayTv = findViewById(R.id.display_tv);

        //mHandler 用于处理主线程消息队列中的子线程消息
        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 1) {
                    //更新 UI
                    mDisplayTv.setText("Jere test: User Handler ");
                }
            }
        };

        mClickBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //开启子线程,子线程处理 UI 工作
                CustomChildThread customThread = new CustomChildThread();
                customThread.start();
            }
        });
    }

    public class CustomChildThread extends Thread {

        @Override
        public void run() {
            //在子线程中创建一个消息对象
            Message childThreadMessage = new Message();
            childThreadMessage.what = 1;
            //将该消息放入主线程的消息队列中
            mHandler.sendMessage(childThreadMessage);
        }
    }
}

4.2 HandlerThread实现

将工作线程的执行结果传递给主线程,从而在主线程中执行相关的 UI 操作,实现工作线程与主线程之间的通信。

Demo例子:利用HandlerThread来实现Progress bar加载,如下图所示?(按消息队列顺序先后执行:Start Progress Bar 1 ->  Start Progress Bar 2 -> Start Progress Bar 1 )

详细代码:

public class HandlerThreadActivity extends AppCompatActivity {
    private final int SET_PROGRESS_BAR_1 = 1;
    private final int SET_PROGRESS_BAR_2 = 2;
    private HandlerThread myHandlerThread;
    private Handler mWorkHandler, mMainHandler;
    private ProgressBar progressBar1, progressBar2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_thread);

        TextView titleTv = findViewById(R.id.title_tv);
        titleTv.setText("HandlerThread");

        progressBar1 = findViewById(R.id.progress_bar_1);
        progressBar2 = findViewById(R.id.progress_bar_2);
        Button startBtn1 = findViewById(R.id.start_progress_bar_1_btn);
        Button startBtn2 = findViewById(R.id.start_progress_bar_2_btn);

        //创建HandlerThread对象
        myHandlerThread = new HandlerThread("myHandlerThread");
        //启动线程
        myHandlerThread.start();

        //创建Handler关联主线程,在主线程上执行run(),可以用于执行UI工作
        mMainHandler = new Handler(getMainLooper());

        //创建工作线程Handler,关联HandlerThread的Looper对象,重写handleMessage()方法,处理消息
        mWorkHandler = new Handler(myHandlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                switch (msg.what) {
                    case SET_PROGRESS_BAR_1:
                        //设置Progress Bar 1
                        for (int i = 1; i <= 4; i++) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                            final int progressSchedule = i;
                            mMainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    progressBar1.setProgress(progressSchedule);
                                }
                            });
                        }
                        break;
                    case SET_PROGRESS_BAR_2:
                        //设置Progress Bar 2
                        for (int i = 1; i <= 4; i++) {
                            try {
                                Thread.sleep(1300);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }

                            final int progressSchedule2 = i;
                            mMainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    progressBar2.setProgress(progressSchedule2);
                                }
                            });
                        }
                        break;
                    default:
                        break;
                }
            }
        };

        startBtn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //通过mWorkHandler发送处理 progress bar 1 的信息
                Message msg = new Message();
                msg.what = SET_PROGRESS_BAR_1;
                mWorkHandler.sendMessage(msg);
            }
        });

        startBtn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //通过mWorkHandler发送处理 progress bar 2 的信息
                Message msg = new Message();
                msg.what = SET_PROGRESS_BAR_2;
                mWorkHandler.sendMessage(msg);
            }
        });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        myHandlerThread.quit();
    }
}

4.3 AsyncTask实现

具体代码请看另一篇博客?Android 多线程之AsyncTask学习

4.4 IntentService实现Demo

具体请看另一篇博客?IntentService例子Demo 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值