赞
踩
这一两个礼拜,一直在忙着做安卓课程设计,刚好昨天在做的时候碰到了一个多线程的应用问题。虽然之前有学习过多线程的知识,但是一直没有真正在自己的开发实践过程中应用过,再加上也有段时间没接触过多线程了,知识也变得模糊了不少。所以乘着这个机会,来把多线程重新温习一下,顺便简单介绍一下它的应用场景。
在没有学习多线程之前,以往我们写的代码都是属于—“顺序编程”,即程序中的所有事物在任意时刻只能执行一个步骤,它会按照我们写代码的顺序执行,然后得出我们预料之中的结果。而多线程编程呢,它的概念刚好相反,它是属于—“并发编程”,在同一时刻可以执行多个步骤(当然,这个执行步骤的多少与快慢 取决于你的硬件基础),这也是java与其他语言相比,得天独厚的优势之处,它能大大提高程序的执行效率。但于此同时,对我们的编程功底要求更深。
虽然说我们在学习java基础的时候,没有接触过多线程,但其实多线程的应用存在于每一个Java程序中------它就是我们所写的main方法(也就是主线程),所有我们之前写的的程序其实都是属于多线程编程的一种方式—“单线程”。讲完了多线程的概念,这里我们还得介绍一下“线程运行图”,关于一个线程的执行顺序以及它的生命周期,废话不多说,直接上图!
关于多线程的实现方式,一般分为两种,这里就直接上代码了,不多解释概念性的玩意了,因为我们平时使用的话也不会太多关注这些的东西,只是有时候需要换着来实现多线程,一时间不一定记得
class ThreadForOuterClass extends Thread{
//重写run方法
public void run(){
/**
* 这里写你要执行的代码
*/
}
}
//执行
new ThreadForOuterClass ().start();
public class ThreadForInnerClass{
public static void main(String[] args){
new Thread(new Runnable(){
@Override
public void run(){
/**
* 这里写你要执行的代码
*/
}
}).start(); //直接执行
}
}
class ThreadForImplRunnable extends Runnable{
//重写run方法
public void run(){
/**
* 这里写你要执行的代码
*/
}
}
//执行
new ThreadForImplRunnable ().start();
这里要讲回我的安卓课程设计了,在开发中,我需要发送一个url调用在线API,然后接收返回的字符串内容进行JSON格式解析。嗯哼~,感觉简单是不是?我开始也是那么觉得,于是乎开始了我的入坑之旅。。。
最开始的代码我是这么写的(大概写出业务核心进行展示,因为代码有点多)
//封装了一个Http工具类,发送一个http请求,向官方api在线获取json数据(字符串)
String result = HttpUtil.doGet(url);
//拿到json格式的字符串,然后进行解析
..........
(该部分代码省略)
..........
然后进行单元测试,ok没问题!可以拿到正常数据,并且解析过程也十分顺利。于是乎我就在genymotion模拟器上开始测试我的app,其他功能没毛病,唯独这部分一直不能正常运行,app界面闪退。花了一个多小时,最后在百度上找到问题的原因。
原因:首先,我们根据前面回顾的多线程知识,可知这段发送http请求的代码是处于主线程(也就是main方法里),而发送HTTP请求又是一个容易出现问题的地方,因为它的响应快慢完全取决于客户端的网络状态,倘若客户端那边网络不好,那主线程就会被阻塞,一直卡在那里等着服务器响应,程序就会出现卡死的现象,这是一种非常不安全也不合理的方式。所以,安卓官方在android3.0以后规定-----凡是需要向服务器发送http请求的代码,必须单独开辟一个程序供其运行。诶呀妈呀,终于找到原因了(笑哭,其实这段代码很明显要使用多线程,只怪我水平菜,还一直停留在顺序编程的思想,没发现这个大bug)
解决办法:其实也就是为发送http请求这段代码开辟一个线程,但是,这里我又出现了一个低级问题,那就是没有考虑到线程的并发性,可能是之前的编程思想没改变过来,一下子没考虑到这个线程执行先后顺序-------(主线程必须等待发送http请求的这个线程)。
这里要介绍击几种实现主线程等待子线程的方法。(这里的发送Http请求只是简单的模拟了一下过程)
今天主要回顾了一下多线程的概念,了解了其最简单的使用场景----主线程等待子线程。当然啦,多线程这方面还有好多知识要学,这里再给大家分享几篇博文,都是与今天的多线程有关。
1.上面提及的java线程池ExecutorService—ExecutorService 等待线程完成的那些事?
2.join,Future以及CountDownLanch-----如何实现java主线程等待子线程执行完毕之后再执行?
3.线程池的优点与具体讲解-----Java ExecutorService四种线程池的例子与说明
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。