Android_开发_Day17_多线程
2019-08-20 本文已影响0人
不要问我问就是百度
Android_开发Day17多线程
目的:
学会使用多线程来处理一些需要同时运行的实际问题,或者是耗时的问题。
技术:
<1> 多线程:线程与进程的关系,进程是一个应用程序打开时就会被创建,他是针对操作系统而言的,而进程是针对一个应用程序而言的,线程之间是可以被同时执行的,因此当主线程即main函数当中有比较好时的代码块时,可以为它开辟一个子线程来同时运行mian方法和该代码块。要开辟一个线程需要建一个线程类继承于thread父类,然后重写run方法,在run方法中写上你要同步执行的代码块。线程类的常用方法:
方法名 | 简述 | 如何使用 |
---|---|---|
getName() | 得到一个线程的名称 | 返回值式一个字符串 |
getState() | 获取线程的状态。PS:线程的状态有新建状态,就绪状态,运行状态,阻塞状态,终止状态 | 返回值是一个静态的字符串 |
getStackTrace() | 获取线程在栈中的位置 | 返回值就是表示此线程的堆栈转储的堆栈跟踪元素数组 |
setName() | 设置线程的名称 | 参数是一个字符串 |
start() | 开始该线程 | 无参也无返回值,调用start后会自动调用run方法 |
<2> 创建一个线程:创建一个线程有两种方法
方法一:
创建一个类继承Thread类,然后重写run方法,run方法里面的内容就是你要执行的代码。
方法二:
创建一个类实现Runnable接口,然后实现里面的run方法,run方法里面的内容也是放你要写的代码,然后用Thread为这个任务分配线程,方式如下:
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread );
thread.start();
方法三:
使用匿名类,代码如下:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int num = 100;
for (int i = 0; i < 100; i++) {
if (num > 0){
System.out.println(Thread.currentThread().getName()+" "+num);
num--;
}
}
}
});
thread.start();
以上代码的简洁方式如下:
new Thread(new Runnable() {
@Override
public void run() {
int num = 100;
for (int i = 0; i < 100; i++) {
if (num > 0){
System.out.println(Thread.currentThread().getName()+" "+num);
num--;
}
}
}
}).start();
方法四:
使用Lambda表达式,方法如下:
new Thread(() ->{
int num = 100;
for (int i = 0; i < 100; i++) {
if (num > 0){
System.out.println(Thread.currentThread().getName()+" "+num);
num--;
}
}
}).start();
<3> 线程的安全:由于线程执行代码的顺序是随机的,因此,当两个线程在操控同一个东西的时候就会出现数据不同步的情况,因此为了不出现这类情况,我们要将线程同步,意思就是当这个线程的代码块没执行完时另一个线程不准执行,这样就避免了两个线程在执行时的数据丢失等风险。因此为了保证线程安全有两种手段:
方法一:
用synchronized(任何一个对象){……}来锁住代码块,这样就不会出错了。
方法二:
用ReentrantLock类来创建一把锁,用法就是调用里面的lock方法和unlock方法,然后在他们之间写上你要同步的代码。
技术如何使用:
模拟开发一个售票系统,有两个地方在同时售票,重庆和上海,票的总数是固定的,只减不加,最后售完为止。要开发一个这个项目首先肯定要用多线程,因为需要同时售票,但是用到多线程就不得不考虑安全问题,因此需要同步线程,代码如下:
public class TestThread {
public static void main(String[] args){
Ticket ticket1 = new Ticket("重庆");
Ticket ticket2 = new Ticket("上海");
ticket1.start();
ticket2.start();
}
}
class Ticket extends Thread{
public static int num = 100;
String name;
public static Object object = new Object();
public Ticket(String name){
this.name = name;
}
@Override
public void run(){
for (int i = 0; i < 100; i++) {
synchronized (object) {
if (num > 0) {
num--;
System.out.println(name + "出票一张,剩余" + num + "张");
}
}
}
}
}
实际使用效果:
截了一部分图从图中是可以看出多线程的,并且数据之间是没有出现错误的情况,说明了线程同步的重要性。
总结:
要使用多线程一定要考虑线程安全问题,不然就会面临出错的风险,因此养成一个使用多线程考虑安全的好习惯不仅仅是在这里有用,在以后的开发中也是会用到的。