Android开发成长史

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 + "张");
                }
            }
        }
    }
}

实际使用效果:

截了一部分图

从图中是可以看出多线程的,并且数据之间是没有出现错误的情况,说明了线程同步的重要性。

总结:

要使用多线程一定要考虑线程安全问题,不然就会面临出错的风险,因此养成一个使用多线程考虑安全的好习惯不仅仅是在这里有用,在以后的开发中也是会用到的。

上一篇下一篇

猜你喜欢

热点阅读