多线程基础学习一:Thread基础学习
2017-08-31 18:06
218 查看
最近开始学习多线程的基础知识,以学习使用为主。
启动线程的方法是start方法,看到网上经常有人问run() 和start()方法区别,自己也尝试了一下,其实run方法,只是实例化了一个对象,调用了对象的一个方法,没有创建新线程,start方法则创建了新线程。
调用start方法执行结果:
可以看到一开始就是main主线程结束了,然后才是新线程执行的结果,如果调用run方法,结果如下:
可以看到,先把run方法执行完,才输出了main线程结束,其实run方法和普通方法调用一样,调用一次执行一次。
网上看到关于守护线程daemon的内容,如果java虚拟机没有非守护线程,就会退出,测试了一下:
设置(默认false)
执行结果
结果只输出了这一句话,看来线程还没执行虚拟机就退出了。但是我注意到,并没有输出“我出现异常了”这句话,一般finally都会执行,看来这种情况finally不执行了。
sleep(毫秒数),这个方法是Thread的类方法,它的注释是这么写的:
首先,sleep方法并没释放锁,当前线程会休眠指定的时间,调用方式一般是这样的:
在哪个线程里写,哪个线程就会休眠执行指定时间。还有另外一种写法,是这样的:
个人觉得多此一举,完全没有必要这么写。
还有一些有特殊意义的写法,比如sleep(0) ,sleep(1),目前还不清楚它们的意义。
测试代码:
输出结果:
可以看到,主线程等待了5秒,新线程没有受影响。
暂停与恢复
suspend() 是暂停方法, resume()是恢复方法,两个都是对象方法,测试代码如下:
执行出现了两中结果,第一种:
第二种:
一直卡在那了
不知道第二种情况为什么会出现,总而言之这两个方法已经过时了,还有其它方面的问题,不要再用了。
终结线程
终止线程有五个方法,分别为stop()、cancle() (Runnable)、 interrupt()(抛出异常或者自己处理)以及标志位结束,其中stop方法已经过期,这个方法不会释放资源。
cancle方法的使用:
执行结果:
interrupt()(抛出异常或者自己处理):
执行结果:
抛出了InterruptedException异常(finally会被执行),这个异常抛出时,会清除中断状态.
标志位结束:
执行结束:
以上集中方式都可以结束线程。
创建一个线程
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("执行结束了"); } } }
执行结束:
正在执行 正在执行 正在执行 正在执行 正在执行 执行结束了
以上集中方式都可以结束线程。
相关文章推荐
- java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提
- 黑马程序员 java基础 继承thread多线程学习日志
- java基础知识回顾之java Thread类学习(七)--java多线程安全问题(死锁)
- JUC学习笔记--Thread多线程基础
- java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)
- 黑马程序员——基础学习(十四)多线程(Thread)和图形界面编程(GUI)
- 多线程基础学习十三:ReentrantLock的了解与使用
- BackgroundWorker .net 2.0 里微软的多线程组件 学习 Cross-thread operation not valid: Control 'RichTextBox1' accessed from a thread other than the thread it was created on.
- Android 学习 之 Looper Handler Thread Messahe 多线程
- Linux多线程基础学习(六)线程属性
- java多线程学习(六)---Thread其它方法
- 黑马程序员——Java零基础学习——初步涉及多线程
- 黑马程序员-----Java基础学习多线程
- 轻松学习多线程-01-基础知识
- Java——Thread线程基础知识学习
- Java基础学习——多线程之控制线程
- java:多线程基础之Runnable、Callable与Thread
- JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)
- 多线程中基础Thread和实现Runnable的区别
- java基础学习之多线程