实现Thread两种方式
1.继承Thread类,简单的代码例子
public class SyncThreadextends Thread {
public SyncThread(String name) {
super(name);
}
@Override
public void run() {
super.run();
// TODO: 执行耗时的逻辑
}
}
调用代码
new SyncThread("线程一").start();
2.实现Runnable接口
public class SyncRunnable implements Runnable {
@Override
public void run() {
// TODO: 执行耗时操作逻辑
}
}
调用代码:
new Thread(new SyncRunnable(),"线程二").start();
Thread主要函数
run()//包含线程运行时所执行的代码
start()//用于启动线程
sleep()/sellp(long mills)//线程休眠,交出CPU,让CPU去执行其他的任务,然后线程进入阻塞状态,sleep方法不会释放锁。
yield()//使当前线程交出cpu,让cpu去执行其他的任务,但不会是线程进程进入阻塞状态,而是重置为就绪状态。yield方法不会释放锁。
join()/join(long millis)/join(long mills,int mills,int nanosecongs)//等待线程终止,直白的说,就是发起该子线程的线程 只有等待该线程运行借宿才能继续往下运行
wait()//交出cpu,让CPU执行其他的任务,让线程进人阻塞状态,同时也会释放锁。
interrupt()//中断线程,自stop函数过时之后,我们通过interrup方法和isInterrupdted()方法来停运正在运行的线程,注意只能终端已经处理阻塞的线程。
getId()//获取当前线程ID
getName()/setNamen()//获取和设置线程的名字
getPriority()/setPriodiTY()//获取和这是线程的优先级,一般property用1-10的整数表示,默认优先级是5,优先级最高的是10,优先级高的线程被执行的机率高。
setDaemon/isDaemo()//设置和判断是否守护保护。
currentThread()//静态函数获取当前线程。
Thread线程的主要状态
1.New一旦被实例化之后就处于new状态
2.Runnable调用了start函数之后就处于Running状态
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;
}
}
}
执行结果
线程同步的几种方式
同样还是以上面的为例
1.同步函数
private void count() {
synchronized (this) {
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)实现线程同步
privatevolatileintcount = 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();
}