博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java线程基础
阅读量:4125 次
发布时间:2019-05-25

本文共 4457 字,大约阅读时间需要 14 分钟。

启动线程

  • 继承类Thread
  • 实现Runnable接口
  • 实现Callable接口(包装成FutureTask)
public class NewThread extends Thread{
/*扩展自Thread类*/ @Override public void run() {
System.out.println("I am extends Thread"); } /*实现Runnable接口*/ private static class UseRun implements Runnable{
@Override public void run() {
System.out.println("I am implements Runnable"); } } /*实现Callable接口,允许有返回值*/ private static class UseCall implements Callable
{
@Override public String call() throws Exception {
System.out.println("I am implements Callable"); return "CallResult"; } } public static void main(String[] args) throws InterruptedException, ExecutionException {
new NewThread().start(); UseRun useRun = new UseRun(); new Thread(useRun).start(); Thread t = new Thread(useRun); t.interrupt(); UseCall useCall = new UseCall(); FutureTask
futureTask = new FutureTask<>(useCall); new Thread(futureTask).start(); System.out.println(futureTask.get()); }}

执行结果:

I am extends ThreadI am implements RunnableI am implements CallableCallResult

停止线程

interrupt()中断一个线程,并不是强行关闭这个线程,把中断标志位置为true

isInterrupted()判断当前线程是否处于中断状态,判断中断标志位是否为true
interrupted()(static方法)判断当前线程是否处于中断状态,中断标志位改为false

public class EndRunnable {
private static class UseRunnable implements Runnable{
@Override public void run() {
String threadName = Thread.currentThread().getName(); System.out.println(threadName+" interrput flag is " +Thread.currentThread().isInterrupted()); while(!Thread.currentThread().isInterrupted()) {
System.out.println(threadName+" is run!"); } System.out.println(threadName+" interrput flag is " +Thread.currentThread().isInterrupted()); } } public static void main(String[] args) throws InterruptedException {
UseRunnable useRunnable = new UseRunnable(); Thread endThread = new Thread(useRunnable,"endThread"); endThread.start(); Thread.sleep(1); endThread.interrupt(); }}

执行结果:

endThread interrput flag is falseendThread is run!endThread is run!endThread is run!endThread is run!endThread interrput flag is true

若方法抛出InterruptedException,线程的中断标志位会被复位成false,需要我们自己在catch里再次中断(调用interrupt方法)

Java里所有阻塞方法都会抛出InterruptedException异常

public class HasInterrputException {
private static SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss_SSS"); private static class UseThread extends Thread{
public UseThread(String name) {
super(name); } @Override public void run() {
String threadName = Thread.currentThread().getName(); System.out.println(threadName+" interrput flag is "+isInterrupted()); while(!isInterrupted()) {
try {
System.out.println("UseThread:"+formater.format(new Date())); Thread.sleep(3000); } catch (InterruptedException e) {
System.out.println(threadName+" catch interrput flag is " +isInterrupted()+ " at " +(formater.format(new Date()))); interrupt(); System.out.println(threadName+" interrput flag is " +isInterrupted()); e.printStackTrace(); } System.out.println(threadName); } System.out.println(threadName+" interrput flag is "+isInterrupted()); } } public static void main(String[] args) throws InterruptedException {
Thread endThread = new UseThread("HasInterrputEx"); endThread.start(); System.out.println("Main:"+formater.format(new Date())); Thread.sleep(800); System.out.println("Main begin interrupt thread:"+formater.format(new Date())); endThread.interrupt(); }}

执行结果:

HasInterrputEx interrput flag is falseUseThread:2019-06-22 23:04:59_236Main:2019-06-22 23:04:59_236Main begin interrupt thread:2019-06-22 23:05:00_038HasInterrputEx catch interrput flag is false at 2019-06-22 23:05:00_038HasInterrputEx interrput flag is truejava.lang.InterruptedException: sleep interrupted	at java.lang.Thread.sleep(Native Method)	at javaStudy.ch1.HasInterrputException$UseThread.run(HasInterrputException.java:31)HasInterrputExHasInterrputEx interrput flag is true

若使用标志位的方式(volatile)控制线程运行和停止,需要注意在线程运行时如果调用了阻塞方法,那么就判断不了标志位进行停止了,要和interrupted()一起进行线程状态判断

线程生命周期

在这里插入图片描述

yield():将线程从运行转到就绪状态,这时可能cpu又选到此线程继续执行
join():线程A执行了B的join方法,线程A必须等待B执行完成了以后,线程A才能继续自己的工作

守护线程:和主线程共死,finally不能保证一定执行,所以线程执行完需要进行关闭释放资源等操作时,一定不能使用守护线程

yieldsleep方法持有的锁不会释放

wait()方法调用前,必须持有锁,调用了wait方法后,锁就会被释放,当wait方法返回(其他线程调用notifyAll唤醒),线程会重新持有锁
notify()方法调用前,必须持有锁,调用notify方法本身不会释放锁,synchronized方法执行完才会释放锁,因此一般将notify放到synchronized方法最后一行

转载地址:http://ifhpi.baihongyu.com/

你可能感兴趣的文章
127个超级实用的JavaScript 代码片段,你千万要收藏好(中)
查看>>
8种ES6中扩展运算符的用法
查看>>
【视频教程】Javascript ES6 教程28—ES6 Promise 实例应用
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(下)
查看>>
【web素材】03-24款后台管理系统网站模板
查看>>
Flex 布局教程:语法篇
查看>>
年薪50万+的90后程序员都经历了什么?
查看>>
2019年哪些外快收入可达到2万以上?
查看>>
【JavaScript 教程】标准库—Date 对象
查看>>
前阿里手淘前端负责人@winter:前端人如何保持竞争力?
查看>>
【JavaScript 教程】面向对象编程——实例对象与 new 命令
查看>>
我在网易做了6年前端,想给求职者4条建议
查看>>
SQL1015N The database is in an inconsistent state. SQLSTATE=55025
查看>>
RQP-DEF-0177
查看>>
Linux查看mac地址
查看>>
Linux修改ip
查看>>
MySQL字段类型的选择与MySQL的查询效率
查看>>
Java的Properties配置文件用法【续】
查看>>
JAVA操作properties文件的代码实例
查看>>
IPS开发手记【一】
查看>>