前言
最近在一直准备总结一下Android上的线程管理,今天先来总结一下Thread使用。
实现Thread两种方式
1.)继承Thread类
/**
* 继承Thread方式 */
private class SyncThread extends Thread {
SyncThread(String name) { super(name);
}
@Override public void run() { //执行耗时操作
}
}示例:
SyncThread syncThread1 = new SyncThread("线程一");
SyncThread syncThread2 = new SyncThread("线程二");
SyncThread syncThread3 = new SyncThread("线程三");
syncThread1.start();
syncThread2.start();
syncThread3.start();2.)实现Runnable接口
/**
* 实现Runnable方式 */
private class SyncRunnable implements Runnable {
@Override public void run() { //执行耗时操作
}
}示例:
SyncRunnable syncRunnable = new SyncRunnable(); Thread syncThread1 = new Thread(syncRunnable, "线程一"); Thread syncThread2 = new Thread(syncRunnable, "线程二"); Thread syncThread3 = new Thread(syncRunnable, "线程三"); syncThread1.start(); syncThread2.start(); syncThread3.start();
Thread主要函数
run()//包含线程运行时所执行的代码
start()//用于启动线程
sleep()/sleep(long millis)//线程休眠,交出CPU,让CPU去执行其他的任务,然后线程进入阻塞状态,sleep方法不会释放锁
yield()//使当前线程交出CPU,让CPU去执行其他的任务,但不会是线程进入阻塞状态,而是重置为就绪状态,yield方法不会释放锁
join()/join(long millis)/join(long millis,int nanoseconds)//等待线程终止,直白的说 就是发起该子线程的线程 只有等待该子线程运行结束才能继续往下运行
wait()//交出cpu,让CPU去执行其他的任务,让线程进入阻塞状态,同时也会释放锁
interrupt()//中断线程,自stop函数过时之后,我们通过interrupt方法和isInterrupted()方法来停止正在运行的线程,注意只能中断已经处于阻塞的线程
getId()//获取当前线程的ID
getName()/setName()//获取和设置线程的名字
getPriority()/setPriority()//获取和这是线程的优先级 一般property用1-10的整数表示,默认优先级是5,优先级最高是10,优先级高的线程被执行的机率高
setDaemon()/isDaemo()//设置和判断是否是守护线程
currentThread()//静态函数获取当前线程
Thread线程主要状态
(1) New 一旦被实例化之后就处于new状态
(2) Runnable 调用了start函数之后就处于Runnable状态
(3) Running 线程被cpu执行 调用run函数之后 就处于Running状态
(4) Blocked 调用join()、sleep()、wait()使线程处于Blocked状态
(5) Dead 线程的run()方法运行完毕或被中断或被异常退出,线程将会到达Dead状态
如何停止一个线程
通过上面的函数列表,我可以知道通过interrupt方法和isInterrupted()方法来停止正在运行的线程,首先必须先让线程处于阻塞状态
/**
* 销毁线程方法 */
private void destroyThread() { try { if (null != thread && Thread.State.RUNNABLE == thread .getState()) { try {
Thread.sleep(500);
thread .interrupt();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
thread = null;
}
}Thread线程同步问题
线程的同步是为了防止多个线程访问一个数据对象时,造成数据不一致的问题。
1.)举例说明:比如多线程操作一个全局变量
private int count = 100; private boolean isRunning = false; private void test1() {
isRunning=true;
SyncThread syncThread1 = new SyncThread("线程一");
SyncThread syncThread2 = new SyncThread("线程二");
SyncThread syncThread3 = new SyncThread("线程三");
syncThread1.start();
syncThread2.start();
syncThread3.start();
} /**
* 继承Thread方式 */
private class SyncThread extends Thread {
SyncThread(String name) { super(name);
}
@Override public void run() { while (isRunning) {
count();
}
}
}未加同步的count函数
private void count() { if (count > 0) {
Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
} else {
isRunning = false;
}
}执行结果:仔细观察会发现有数据错乱的现象
添加同步的count函数
private void count() { synchronized (this) { if (count > 0) {
Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
} else {
isRunning = false;
}
}
}2.)线程同步的几种方式
同样还是以上面的为例
(1)同步函数
private synchronized void count() { if (count > 0) {
Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
} else {
isRunning = false;
}
}(2)同步代码块
private void count() { synchronized (this) { if (count > 0) {
Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
} else {
isRunning = false;
}
}
}(3)使用特殊域变量(volatile)实现线程同步
private volatile int count = 1000;
a.volatile关键字为域变量的访问提供了一种免锁机制,
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
(4)使用重入锁实现线程同步
ReentrantLock() : 创建一个ReentrantLock实例
lock() : 获得锁
unlock() : 释放锁
private void count() {
lock.lock(); if (count > 0) {
Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
} else {
isRunning = false;
}
lock.unlock();
}
干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
