Java Thread线程

作为一名Android工程师,相信大家都应该经常会用到线程,或者异步操作,但是操作线程是一件有风险的事,下面我会列出我遇到过的一些坑。
由于技术有限,可能会有不对的地方,欢迎大家批评、指出问题,我会继续更新并改正,也欢迎交流,共同进步。
线程的概述(Introduction)

线程是一个程序的多个执行路径,执行调度的单位,依托于进程存在。 线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间也叫做线程栈,是在建立线程时由系统分配的,主要用来保存线程内部所使用的数据,如线程执行函数中所定义的变量。

注意:Java中的多线程是一种抢占机制而不是分时机制。抢占机制指的是有多个线程处于可运行状态,但是只允许一个线程在运行,他们通过竞争的方式抢占CPU。

基本状态:就绪、阻塞和运行


下面通过代码实际操作来讲解:

  • 线程的创建:线程的创建有两种方式
    ①第一种(继承Thread):
    public static class MineThread extends Thread {

        @Override
        public void run() {
            while (!stop) {
                System.out.println("Thread is running . . . ");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

②第二种(实现Runnalbe接口,重载Runnalbe接口中的run()方法):

public static class MineThread implements Runnable{

        @Override
        public void run() {
            while (!stopB) {
                System.out.println("Thread is running . . . ");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

这两种方法的区别我就不去说了,我曾看到过一篇很好的博客,介绍le这两种的区别,感兴趣的同学,可以去看看:
http://www.cnblogs.com/whgw/archive/2011/10/03/2198506.html


  • 线程的停止:
    终止线程的方法有三种:

    1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

    2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。

    3. 使用interrupt方法中断线程。

在这三张方法中,第二种不可用,第三种有时候会出现无法终止线程的情况,实际上interrupt是终止阻塞的意思,所以,实际上我们如果想停止一个线程的最好的方法是使用退出标志位,然后再调用interrupt方法,一定要注意先后顺序。
下面我们分别通过代码测试这三种方法:


使用退出标志:

public class ThreadDemo {
    public static boolean stop = false;

    public static void main(String[] args) {
        MineThread thread = new MineThread();
        thread.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Stop thread . . . ");
        stop = true;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hread.isAlive()=" + thread.isAlive());
    }

    public static class MineThread extends Thread {

        @Override
        public void run() {
            while (!stop) {
                System.out.println("Thread is running . . . ");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

运行结果:
这里写图片描述

从运行结果看,线程被终止,说明此方法可行。


使用interrupt方法中断线程:

public class ThreadDemo {
    public static boolean stop = false;

    public static void main(String[] args) {
        MineThread thread = new MineThread();
        thread.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Stop thread . . . ");
        try {
            thread.interrupt();
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hread.isAlive()=" + thread.isAlive());
    }

    public static class MineThread extends Thread {

        @Override
        public void run() {
            while (!stop) {
                System.out.println("Thread is running . . . ");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println(e.toString());
                }
            }
        }
    }
}

运行结果:
这里写图片描述

从上图运行结果看,interrupt只是中断了线程阻塞,而并没有终止线程。再看下面的代码:

public class ThreadDemo {
    public static boolean stop = false;

    public static void main(String[] args) {
        MineThread thread = new MineThread();
        thread.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Stop thread . . . ");
        try {
            thread.interrupt();
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hread.isAlive()=" + thread.isAlive());
    }

    public static class MineThread extends Thread {

        @Override
        public void run() {
            long startTime = System.currentTimeMillis();
            while (!stop) {
                while (System.currentTimeMillis() - startTime > 1000) {
                    startTime = System.currentTimeMillis();
                    System.out.println("Thread is running . . . ");
                }
            }
        }
    }
}

这段代码和上一段代码的区别在于没有调用Thread.sleep()方法阻塞线程,此时你会发现interrupt方法实际上没有起到任何实质性的作用。运行结果如下:
这里写图片描述


退出标志+interrupt :

public class ThreadDemo {
    public static boolean stop = false;

    public static void main(String[] args) {
        MineThread thread = new MineThread();
        thread.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Stop thread . . . ");
        stop = true;
        thread.interrupt();
        try {
            thread.interrupt();
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hread.isAlive()=" + thread.isAlive());
    }

    public static class MineThread extends Thread {

        @Override
        public void run() {
            while (!stop) {
                System.out.println("Thread is running . . . ");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println(e.toString());
                }
            }
        }
    }
}

运行结果:
这里写图片描述

总结:从上面的运行结果来看,终止一个线程的最好方法是退出标志+interrupt,但是一定要注意先后顺序:退出标志–>interrupt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值