多线程基础学习一:Thread基础学习

最近开始学习多线程的基础知识,以学习使用为主。

创建一个线程

Thread是一个实现了Runnable接口的实现类,所以创建线程只要集成重写run方法就可以了。

/**
 * Created by nyl
 * 2017/9/15 0015
 */
public class DaemonTest {

    public static void main (String[] args) {

        Thread thread = new MyThread();
        //thread.setDaemon(true);
        thread.start();
        System.out.println("main主线程结束");
    }

    private static class MyThread extends Thread{

        @Override
        public void run () {
            int i = 0;
            while(i <= 10) {
                try {
                    Thread.sleep(1000);
                    i++;
                    System.out.println("执行第" + i  + "次");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.println("我出现异常了");
                }
            }

        }
    }    
}

启动线程的方法是start方法,看到网上经常有人问run() 和start()方法区别,自己也尝试了一下,其实run方法,只是实例化了一个对象,调用了对象的一个方法,没有创建新线程,start方法则创建了新线程。
调用start方法执行结果:

main主线程结束
执行第1次
执行第2次
执行第3次
执行第4次
执行第5次
执行第6次
执行第7次
执行第8次
执行第9次
执行第10次
执行第11次

可以看到一开始就是main主线程结束了,然后才是新线程执行的结果,如果调用run方法,结果如下:

执行第2次
执行第3次
执行第4次
执行第5次
执行第6次
执行第7次
执行第8次
执行第9次
执行第10次
执行第11次
执行第12次
main主线程结束

可以看到,先把run方法执行完,才输出了main线程结束,其实run方法和普通方法调用一样,调用一次执行一次。

网上看到关于守护线程daemon的内容,如果java虚拟机没有非守护线程,就会退出,测试了一下:
设置(默认false)

thread.setDaemon(true);

执行结果

main主线程结束

结果只输出了这一句话,看来线程还没执行虚拟机就退出了。但是我注意到,并没有输出“我出现异常了”这句话,一般finally都会执行,看来这种情况finally不执行了。

常用方法

  • 等待一段时间继续执行
    sleep(毫秒数),这个方法是Thread的类方法,它的注释是这么写的:
如果任何线程中断了当前线程。当抛出此异常时,当前线程的中断状态被清除。

首先,sleep方法并没释放锁,当前线程会休眠指定的时间,调用方式一般是这样的:

 Thread.sleep(1000);

在哪个线程里写,哪个线程就会休眠执行指定时间。还有另外一种写法,是这样的:

Thread.currentThread().sleep(1000);

个人觉得多此一举,完全没有必要这么写。

还有一些有特殊意义的写法,比如sleep(0) ,sleep(1),目前还不清楚它们的意义。
测试代码:

/**
 * Created by nyl
 * 2017/9/15 0015
 */
public class DaemonTest {

    public static void main (String[] args) {

        Thread thread = new MyThread();
        //thread.setDaemon(true);
        thread.start();

        System.out.println("main主线程结束");
        try {
            //thread.stop();
            Thread.sleep(5000);
            System.out.println("等待5s结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static class MyThread extends Thread{

        @Override
        public void run () {
            int i = 0;
            while(i <= 10) {
                try {
                    Thread.sleep(1000);
                    i++;
                    System.out.println("执行第" + (i + 1) + "次");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //System.out.println("我出现异常了");
                }
            }

        }
    }

}

输出结果:

执行第2次
执行第3次
执行第4次
执行第5次
执行第6次
等待5s结束
执行第7次
执行第8次
执行第9次
执行第10次
执行第11次
执行第12次

可以看到,主线程等待了5秒,新线程没有受影响。

  • 暂停与恢复
    suspend() 是暂停方法, resume()是恢复方法,两个都是对象方法,测试代码如下:
public class PasueTest {

    public static void main (String[] args) {

        Thread thread = new MyThread();
        thread.start();

        System.out.println("main主线程结束");
        try {
            thread.suspend();
            Thread.sleep(5000);
            System.out.println("等待5s结束");
            System.out.println("暂停执行5s");
            thread.resume();
            System.out.println("恢复重新执行");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static class MyThread extends Thread{

        @Override
        public void run () {
            System.out.println("我执行了");
        }
    }
}

执行出现了两中结果,第一种:

main主线程结束
等待5s结束
暂停执行5s
恢复重新执行
我执行了

第二种:

main主线程结束

一直卡在那了
不知道第二种情况为什么会出现,总而言之这两个方法已经过时了,还有其它方面的问题,不要再用了。

  • 终结线程

终止线程有五个方法,分别为stop()、cancle() (Runnable)、 interrupt()(抛出异常或者自己处理)以及标志位结束,其中stop方法已经过期,这个方法不会释放资源。

cancle方法的使用:

public class CancleTest {

    public static void main (String[] args) {

        Thread first = new Thread(new CancleThread());
        first.setDaemon(true);
        first.start();
        SleepUtil.sleep(5000);
        System.out.println("线程取消了");
    }

    static class CancleThread implements Runnable {

        @Override
        public void run () {

            while (true) {
                SleepUtil.sleep(1000);
                System.out.println("我执行了");
            }
        }
    }
}

执行结果:

我执行了
我执行了
我执行了
我执行了
我执行了
线程取消了

interrupt()(抛出异常或者自己处理):

public class InterruptedTest {

    public static void main (String[] args) {

        Thread first = new InterruptedThread();
        first.setDaemon(true);
        Thread second = new Interrupted1Thread();
        second.setDaemon(true);
        first.start();
        second.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        first.interrupt();      
        System.out.println("first interrupt is " + first.isInterrupted());      

        SleepUtil.sleep(50);
    }

    static class InterruptedThread extends Thread {

        @Override
        public void run () {
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println("中断状态是:" + Thread.interrupted());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }    
}

执行结果:

中断状态是:false
中断状态是:false
中断状态是:false
中断状态是:false
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at learn.threadlearn.InterruptedTest$InterruptedThread.run(InterruptedTest.java:40)
中断状态是:false
first interrupt is true

抛出了InterruptedException异常(finally会被执行),这个异常抛出时,会清除中断状态.

标志位结束:

public class FlagTest {

    private static boolean type = true; // 标志位, 这样写不严谨,有风险

    public static void main (String[] args) {

        FlagThread  first = new FlagThread();
        first.setDaemon(true);
        first.start();
        SleepUtil.sleep(5000);
        type = false;
        SleepUtil.sleep(2000);
    }

    static class FlagThread extends  Thread {


        @Override
        public void run () {
            while (type) {
                SleepUtil.sleep(1000);
                System.out.println("正在执行");
            }

            System.out.println("执行结束了");
        }
    }

}

执行结束:

正在执行
正在执行
正在执行
正在执行
正在执行
执行结束了

以上集中方式都可以结束线程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值