Java多线程(一)
来源:互联网 发布:女生用电动牙刷知乎 编辑:程序博客网 时间:2024/05/25 20:01
Java线程被称为是轻量级的进程,一个进程可以有多个线程,一个线程必须要有一个父进程。线程是独立运行的。
Java使用Thread类代表线程,所有线程对象都必须是Thread类或者子类的实例。
同一个进程可以由多个线程并发进行。多线程之间内存共享容易,实现多任务并发效率高,多线程是非常有用的。
创建多线程
创建线程有三种方式:继承Thread类,实现Runnable接口,使用Callable和Future创建
一、继承Thread类创建
1.定义子类,重写run()方法,run()方法是线程执行体
2.创建子类实例,即创建了线程对象
3.调用线程对象start()方法启动线程
public class ChildThread extends Thread{ public void run(){ //这里写要执行的语句执行体 } public static void main(String[] args){ Thread thread_1 = new ChildThread(); thread_1.start(); }}
使用继承Thread类的方法创建线程类时,多线程间不能共享线程类实例变量。
二、实现Runnable接口创建
1.定义Runnable接口的实现类,重写run()方法,依然是线程的执行体
2.创建实例,以此实例为Thread的target创建Thread对象,该Thread对象是真正的线程对象
public class RunThread implements Runnable{ public void run(){ //这里写要执行的语句执行体 } public static void main(String[] args){ RunThread runThread = new RunThread();<span style="white-space:pre"></span>//创建Runnable对象 Thread trueThread = new Thread(runThread);<span style="white-space:pre"></span>//用Runnable对象创建线程对象 trueThread.start(); }}和继承Thread相比,实现Runnable接口的方法不能直接创建线程对象,必须先创建Runnable对象在进一步创建线程对象。
Runnable接口是函数式接口(只有一个抽象方法的接口,可以包含多个默认方法和类方法),可用Lambda表达式创建Runnable对象。
三、使用Callable和Future创建线程
Callable提供了一个call()方法作为线程执行体,call()有返回值,并且可以声明抛出异常
Future接口代表call()方法的返回值,有一个FutureTask实现类,实现了Future和Runnable接口,可以作为Thread类的target
Callable接口同样是函数式接口,可用Lambda表达式创建Callable对象。
线程启动步骤:
1.创建Callable接口实现类,实现call()方法,call()方法作为线程执行体,有返回值,再创建实现类实例
2.使用FutureTask包装Callable对象,该Futuretask对象封装了返回值
3.使用FutureTask对象创建启动线程
4.调用FutureTask对象的get()方法获得子线程结束的返回值
public class FirstCall implements Callable{ public void call throws Exception(){ //这里写要执行的语句执行体 return ;//可以有返回值 } public static void main(String[] args){ Callable callable = new FirstCall();//创建Callable对象 FutureTask firstTask = new FutureTask(callable);//创建FutureTask对象 Thread trueThread = new Thread(firstTask);//用FutureTask对象创建线程对象 trueThread.start(); }}也可以使用Lambda表达式直接创建Callable对象,这样就无需创建Callable实现类和Callable对象了。
public class CallThread{ public static void main(String[] args){ CallThread callhread = new CallThread();//创建Callable方法 FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)()->{ //这里直接写call方法里面执行体,不用写call() }); new Thread(task).start(); }}
三种实现多线程的方式都可以实现,实现Runnable接口和实现Callable接口方式基本相同,可以归为一种方式。这种方式和继承Thread差别在于:
采用Runnable或Callable接口的方式优缺点:
1.线程类只实现了Runnable或Callable接口,可以继承其他类
2.多个线程可以共享一个target,适合多个相同线程处理同一份资源。
3.缺点:编程复杂,想访问当前线程,必须用Thread.currentThread()方法
采用继承Thread创建方式的优缺点:
1.编写简单,直接用this即可获得当前线程
2.缺点:已经继承了Thread类,不能继承其他父类
因此通常采用实现Runnable接口或Callable接口创建多线程
线程生命周期
线程生命周期包括新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead) 5种
New新建一个线程,当线程对象调用start()线程处于就绪状态,表示可以运行了,只能对处于新建状态的线程调用start()方法,否则会引发异常。
线程一下情况会进入阻塞状态:
1.调用sleep()主动放弃
2.调用了阻塞IO的方法,该方法返回之前,线程被阻塞
3.试图获得一个同步监视器,但该同步监视器正被其他线程持有
4.等待某个通知(notify)
5.调用了suspend()方法将线程挂起
针对这些情况,发生如下情况可解除阻塞:
1.调用sleep()方法的线程经过了指定时间
2.调用的阻塞IO方法已经返回
3.成功获得同步监视器
4.在等待某个通知时,其他线程发出通知
5.调用resume()恢复
测试线程是否死亡可调用线程对象的isAlive()方法,不要对已经死亡的线程调用start()方法,否则会引发异常
- java多线程:多线程(一)
- Java--多线程(一)
- java(多线程 一)
- JAVA多线程(一)
- java多线程(一)
- Java多线程(一)
- Java多线程(一)
- java多线程(一)
- Java多线程(一)
- Java多线程(一)
- java---多线程(一)
- Java多线程(一)
- Java多线程(一)
- java多线程(一)
- java多线程(一)
- Java多线程(一)
- Java多线程(一)
- Java多线程(一)
- 指定git路径,拉取远程所有的分支到本地,脚本
- Tomcat内存配置
- APK发布*
- 其他
- LeetCode 223 Rectangle Area
- Java多线程(一)
- 【每天听见吴晓波-2016-07-04】上海房价未来五年还会翻番
- java -- jvm载入器
- OC中的connection 和 session
- 很好的一个关于maven工程创建的文章
- Spring 注解 new创建对象后失效
- 如何在不引用头文件的情况下调用category里面的方法
- Spring重试支持Spring Retry
- Request的getParameter和getAttribute方法的区别