Android线程

Android的应用层都是Java写的,所以很多语法上的东西就是Java的,只不过某些类在原有基础上进行了包装,毕竟android跟java web,se之类的生产环境不一样,而线程又是java中一块很重要的知识,线程控制的好不好也关系到应用性能提升大不大,毕竟不是Java出身,所以简单的说说java的线程

多线程

扯到线程,就不免会说道进程,简答来数进程就是内存中运行的应用程序有独立的内存空间,而线程则是进程的组成,线程即达成目标的一个任务。
那么我们为什么使用多线程呢?如今cpu已经进入4核,八核时代,如何充分利用硬件资源去实现一个程序催生了多线程。
举个简单的例子,运一批货,在一个双车道的道路上,如果按顺序发车的话,货物到达肯定要慢点,同时发货的话,理想情况时间就少了一半。

Java的多线程
一般Java中实现多线程无非两种方式:
  • 继承Thread
class NewThread extends Thread {    
@Override    
public void run() {        
        super.run();    
        }
}
  • new Thread将任务放到Runnable里面
new Thread(new Runnable() {    
@Override    
public void run() {            
      }
}).start();

需要注意的是,调用start方法后,线程不是立即开启,而是等待系统分配时间片(由于系统是随机分配时间片,所以线程的调度存在不确定性)

线程状态
线程状态.png
  • 新建状态(New):**当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
  • 就绪状态(Runnable):**当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
  • 运行状态(Running):**当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
  • 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
    1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
    2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
    3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  • 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
线程优先级

Java的线程是具有优先级的,可以通过setPriority()设置线程的优先级,控制线程的重要性(拥有较大机会获取系统调度),Thread有3个控制线程优先级的常量

  • static int MAX_PRIORITY ----10
  • static int MIN_PRIORITY-----1
  • static int NORM_PRIORITY---5
常见线程常用函数

1.sleep(long mills):让当前线程休眠指定的毫秒数
2.join():让主线程等待调用该函数的线程结束再执行(所在线程等待调用该方法的线程变量所在的线程执行完毕)
应用情形:当主线程需要实时使用子线程的处理结果,有点像阻塞式的编程
3.yield():暂停当前线程,让出时间片
实质是将该线程调回到runnable状态重新等待调度,高优先级线程会被先调用,同等级无法保证让出时间片(进入了统一等待队列,系统还是会选中当前线程)
4.setPriority(int priority):上面有说过
5.interrupt():野蛮方式中断线程,可能会导致资源无法释放
6.wait():等待拥有同样资源锁的线程的执行,线程同步的一个方法,主要关系到对资源锁定问题,后面讨论
7.notify():唤醒拥有同样资源锁的线程


备注:sleep()与wait()区别:sleep的同时不释放同步锁,也就是说sleep的同时拥有同样资源锁的线程不会拿到时间片,而wait()的时候是释放同步锁,让其他拥有同等资源锁的线程获得时间片(必须放在synchronized块内)


线程同步问题

这个应该是线程里面最重要,也是最难的部分了,主要由于系统调度的不确定性引起,一般不做线程同步的话,出现了某些问题,调试都很难调试出来
数据的同步在数据库里面非常常见,设想线程A,B同时对一个变量进行++操作

int res = 0;
class A extends Thread {    
@Override   
 public void run() {       
super.run();       
 res=res+1;       
System.out.print("A:res" + res);    
}}
class B extends Thread {   
 @Override    
public void run() {        
super.run();       
 res=res+1;        
System.out.print("B:res" + res);    }}```
上述代码会有两种不同的输出
A:1
B:2
或者
B:1
A:2
这可能跟我预想的结果就不一样了,因此我们需要对资源进行同步
######synshronized关键字
这是用来加同步锁的关键字,他有两种作用域
1. 对象:某个对象内synchronized methodA(){},可以锁住这个对象的该方法(若该对象拥有多个synchronized方法,加锁后其它synchronized方法也无法调用),但不影响不同对象
2. 类:synchronized static methodA(){},对所有对象起效
除了方法前可以加synchronized,某个区块也可以加,他们的实质都是锁对象

```synchronized methodA(){} //锁对象 
synchronized static methodA(){} //锁类```
等同于 
```methodA(){synchronized(obj){} } //锁对象 
methodA(){
synchronized(obj.class){}}```
synchronized搭配wait(),notify()方法使用,wait()调用后,不执行wait()后面的代码,notify()后继续执行上次wait()后的代码

######lock同步锁
方便的解决同步问题的另一方案

class X {
// 显示定义Lock同步锁对象,此对象与共享资源具有一对一关系
private final Lock lock = new ReentrantLock();
public void m(){
// 加锁 lock.lock();
//... 需要进行线程安全同步的代码
// 释放Lock锁
lock.unlock(); } }


可以参考下Condition实现

######线程数据传递

由于线程的不确定性,所以线程间的通信,也不像普通的同步模式下的通信
1. 构造方法传递数据 由于构造方法是线程一开始就传入所以不存在同步问题,可通过重载构造方法传入参数
2. 通过公开方法赋值,类的属性器赋值或者读取
前两个都建立在宿主线程与被调线程的通信,下面就是线程与线程之间(并无直接关联)
3. 通过同步控制,访问共有对象(synchronized,wait,notify等)
4. 管道流(这个不是很了解,望高手指教)
---
接下来就谈谈Runnable,Callable<V>,Future。
由于Runnable里面的run函数返回为void,因此我们无法观察任务的状态,Callable<V>正好解决了这个问题

public interface Callable<V> {
/**

  • Computes a result, or throws an exception if unable to do so.
  • @return computed result
  • @throws Exception if unable to compute a result
    */
    V call() throw Exception;
    }```
    Future又是什么东西呢,
public interface Future<V> {  
boolean cancel(boolean mayInterruptIfRunning);   
boolean isCancelled();   
boolean isDone();
V get() throws InterruptedException,ExecutionException;   
V get(long timeout, TimeUnit unit)        
throws InterruptedException, ExecutionException, TimeoutException;
}```
* cancel取消任务
* isCancelled 返回任务是否被取消
* get 获取任务这行结果,阻塞方法,等到任务正常完成才会返回值
* get(long,TimeUnit)在规定时间内无返回结果就返回null

所以Future只是个接口因此我们只能使用它的实现

public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}```
FutrueTask实现了RunnableFuture<v>,RunnableFuture<v>又继承自Runnable,Future<v>,Callable<v>经常搭配ExcutorService一起使用

public FutureTask(Callable<V> callable) {}
public FutureTask(Runnable runnable, V result) {}```
FutureTask提供了两个构造函数,实质都是实现Runnable与Future<v>接口,[FutureTask,Callable<V>使用](http://www.cnblogs.com/dolphin0520/p/3949310.html)

----
写作思路大抵发散性的 有相关的就查阅下,篇幅比较长,若有错误请大家指正,下次接着写线程池
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容