JAVA多线程基础知识
来源:互联网 发布:淘宝上被骗怎么投诉 编辑:程序博客网 时间:2024/05/17 23:07
开篇
毕业三四年了,一直没怎么用过多线程,一直停留在继承Thread 和 实现Runnable接口上,最近开始写多线程了发现没我想象那么简单,今天开始从头过一遍java的多线程的知识包括最基础的细节,希望对后面的开发以及以后的面试有所帮助。
进程与线程
- 说到进程,打开我们操作系统的任务管理器->进程,这里应该不用多说了。看看官方解释:进程是操作系统结构的基础;是一次程序的运行;它是系统进行资源分配和调度的一个单位。
- 线程是进程中独立运行的子任务。
- 一个进程在运行时至少有一个线程,一个mian方法就是一个进程,同时默认有一个线程。
- 多线程是异步的,不是代码上下执行的顺序。
使用多线程
这里我就不多说了,看看Thread的源代码,它也是实现了Runnable的接口,java不能多继承,因此两种方式类似,我就直接贴代码了。
继承Thread
package thread.t001;public class MyThread extends Thread {@Overridepublic void run() {System.out.println("MyThread"+Thread.currentThread().getName());}public static void main(String[] args) {MyThread m = new MyThread();m.start();}}
实现Runnable接口
package thread.t001;public class MyThread2 implements Runnable{public void run() {System.out.println("Runnable: "+Thread.currentThread().getName());}public static void main(String[] args) {MyThread2 m = new MyThread2();Thread t = new Thread(m);t.start();}}
以上两种的调用方法看似有点区别,其实实质是一样的。调用Thread的start方法,执行多线程类的run()方法
注意几点,同一个线程不能多次start会报
Exception in thread "main" java.lang.IllegalThreadStateException异常
实例变量与线程安全
不共享数据
package thread.t001;public class MyTask extends Thread{ int count = 5; @Override public void run() { while(count > 0){ count--; System.out.println(Thread.currentThread().getName()+":"+count); }; } public static void main(String[] args) { MyTask t1 = new MyTask(); t1.start(); MyTask t2 = new MyTask(); t2.start(); }}
结果:
Thread-0:4Thread-0:3Thread-0:2Thread-0:1Thread-0:0Thread-1:4Thread-1:3Thread-1:2Thread-1:1Thread-1:0
共享数据
package thread.t001;public class MyTask extends Thread{ int count = 5; @Override synchronized public void run() { while(count > 0){ count--; System.out.println(Thread.currentThread().getName()+":"+count); }; } public static void main(String[] args) { MyTask t1 = new MyTask(); Thread t = new Thread(t1); t.start(); Thread t2 = new Thread(t1); t2.start(); }}
结果:
Thread-1:4Thread-2:3Thread-1:2Thread-2:1Thread-1:0通过上面两段代码可以发现,共享数据只创建了一次资源,用两个线程去跑,结果是两个线程共同消费了count,但是细心地你发现了共享数据的方法前加了synchronized关键字这个稍后说;
但是不共享数据的没有加,这是因为共享资源的多线程中,线程是不安全的,因为多个线程操作的同一个资源count,如果count变量做为该方法的局部变量,则是线程安全的。
多线程常用方法
currentThread()方法可返回代码段正在被哪个线程调用的信息;
isAlive()方法判断当前的线程是否处于活动状态;
sleep()的作用是在制定的毫秒书内让当前正在执行的线程休眠;
getId()方法的作用是取得线程的唯一标示;
以上方法就不一一且代码测试了,重点看一下停止一个线程interrupt(0方法
停止一个线程
简单粗暴的方法是是stop();
调用stop()会报出java.lang.ThreadDeath异常,此异常不需要显示的扑捉,stop()方法jdk已不再建议使用,
使用stop()方法如果强制让线程停止侧有可能使一些清理性的工作得不到完成
对锁定的对象进行了“解锁”,导致数据得不到同步的处理,出现数据不一致的问题
停止一个线程有以下几种办法:
interrupt -> isterrupt -> return
interrupt -> isterrupt -> break
interrupt -> isterrupt -> throw exception
需要用到isterrupt()方法配合使用或者interrupted()方法,判断是否为true
我举一个例子说明下,其它方法类似:
package thread.t001;public class MyInterrupt extends Thread {@Overridepublic void run() {try {for (int i=0; i<100; i++){if (i == 50){Thread.currentThread().interrupt();if (Thread.currentThread().interrupted()){throw new InterruptedException();}}System.out.println(i);}System.out.println("我是run的结尾!");} catch (Exception e) {}}}
加粗两三句代码可结束一个线程,
Thread.currentThread().interrupt();将此线程标记为停止状态为true
Thread.currentThread().interrupted()如果此线程为停止状态
throw new InterruptedException();抛出一个异常跳出;这一步可以用break(此方法看逻辑,虽然跳出了循环,但是for下面的还会执行)
通过以上可以得出 interrupt()方法并不是将线程停掉,而是做了一个标记,然后使用interrupted判断此线程的标记,如果标记了则终止;
interrupt()与isterrupt
都可以判断线程当前的状态
interrupt() 判断之后会清空此线程的状态,如果第一次判断为true,则之后再调用则为false
isterrupt()不清空状态
在sleep()状态下停止线程
在sleep()中interrupt 和 interrupt再sleep()都会进入catch
yield()作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间,但放弃时间不确定,有可能刚刚放弃,马上又获得CPU是时间片
suspend()暂停,resume()继续
这两个方法有个缺点就是独占资源,会导致共享的数据其它线程无法访问,也会导致数据不同步(比如给两个值赋值,第一个赋完值暂停了还没有继续,然后其它线程调用了get方法获取这两个值)
线程的优先级别
在操作系统中,线程可以划分优先级,优先级较高的线程得到的CPU资源较多,也就是CPU、优先执行优先级较高的线程对象中的任务
setPriority();优先级级别为1-10
如果小于1或者大于10则会抛出异常
优先级高不一定就先执行完
线程优先级的继承特性
在Java中,线程的优先级具有继承性,比如A线程启动B线程,则B线程的优先级与A线程是一样的
守护线程(Daemon)
Java线程中有两种线程,一种是用户线程,一种是守护线程
守护线程是一种特殊的线程,它的特性有“陪伴”的含义,当进程不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾回收线程
今天就先学习整理到这里,下一篇重点学习一下 多线程的并发。
- Java多线程基础知识
- Java多线程基础知识
- java多线程基础知识
- Java多线程基础知识
- java多线程基础知识1
- Java基础知识:多线程
- Java基础知识:多线程
- Java 基础知识---多线程
- java多线程基础知识总结
- Java基础知识 -- 多线程
- java基础知识---多线程、同步
- Java多线程完整版基础知识
- JAVA多线程基础知识
- java基础知识-多线程
- JAVA多线程 基础知识 001
- Java多线程--基础知识
- Java多线程完整版基础知识
- java多线程基础知识(一)
- 电路与Multisim基础 导线交叉的正确画法
- 读书笔记-《Web全栈工程师的自我修养》-余果:积累自己的作品集
- retrofit 常见问题整理
- 关于Java字符串(String)10个最常见问题
- c++常用字符串处理
- JAVA多线程基础知识
- kettle4.0连不上远程mysql的解决方法
- 编程思想总结-网剑
- 初学Java Web——xml(一)
- C/C++ 学习笔记:结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法
- java cookie实现显示用户上次登录时间
- 《产品前线:48位一线互联网产品经理的智慧与实战》读后感
- 风雪
- Redhat Linux5.3 32bit操作系统LVM学习笔记之二(在线调整镜像卷大小)