阅读建议

最好使用电脑观看。

如果你非要使用手机观看,那请把字体调整到最小,这样观看效果会好一些。

碎片化阅读并不会得到真正的知识提升,要想有提升还得找张书桌认认真真看一会书,或者我们公众号的文章。

如果觉得不错,各位帮着转发转发,如果觉得有问题或者写的哪不清晰,务必私聊我~

本篇文章不是java语法的基本教程!在阅读之前,请保证你有面向对象的编程基础,熟悉封装、继承、多态,否则的话,你不适合阅读本篇文章,先学一下基础吧~

Java线程基本概念

哈哈,上边扯了好大一会儿犊子才绕到java语法这?。没办法呀,你不了解故事背景直接看剧情总是会有些懵逼的~java语言中的线程是对操作系统线程的一种抽象,有些地方可能不太一致,遇到了再和大家说哈~

main线程

我们之前说过,main方法是程序入口,我们对已经编译好的class文件调用java命令时就可以运行一个java程序。这个过程中,其实系统自动为我们创建了一个进程和一个线程,而且这个线程的名字就叫做main。main线程是用来执行我们的程序的,不过系统还会为我们创建一些辅助线程来帮助main线程的执行,现在就先不说它们是啥了,等遇到了再说哈~

除了系统自己创建的这个main线程以外,我们还可以自己在程序里创建一些线程。不过我们前边说过,线程其实是去执行任务的,所以我们先看怎么定义任务。

定义任务

java中的任务被抽象成了一个Runnable接口:

public interface Runnable {

public void run();

}

我们的自定义任务需要去实现这个接口,并把任务的详细内容写在覆盖的run方法里,比如我们定义一个输出一个字符串的任务:

public class PrintTask implements Runnable {

@Override

public void run() {

System.out.println("输出一行字");

}

}

看到了吧,定义一个任务就是这么简单哈~不过光有任务没啥卵用,需要创建一个线程去运行这个任务

Thread类

java中的Thread类来代表一个线程,我们需要关注它的这几种构造方法:

Thread(Runnable target, String name)

在创建线程对象的时候传入需要执行的任务以及这个线程的名称。

Thread(Runnable target)

只传入需要执行的任务,名称是系统自动生成的,或者可以在创建对象后再通过别的方法修改名称。

Thread(String name)

只传入待创建线程的名称。

Thread()

啥都不传,就是单纯构造一个线程对象而已~

执行任务

Thread类的start()方法负责开始执行一个线程,让一个线程运行起来有这么两种方法:

创建Thread对象的时候指定需要执行的任务:

public class Test {

public static void main(String[] args) {

new Thread(new PrintTask()).start();

}

}

执行结果是:

输出一行字

通过继承Thread类并覆盖run方法:

Thread类本身就代表了一个Runnable任务,我们看Thread类的定义:

public class Thread implements Runnable {

private Runnable target;

@Override

public void run() {

if (target != null) {

target.run();

}

}

// ... 为省略篇幅,省略其他方法和字段

}

其中的target就是在构造方法里传入的,如果构造方法不传这个字段的话,很显然run方法就是一个空实现,所以如果我们想运行这个线程,就继承它并且覆盖一下run方法吧:

public class PrintThread extends Thread {

@Override

public void run() {

System.out.println("输出一行字");

}

}

因为PrintThread中已经有一个任务了,所以直接调用start方法运行它就好:

public class Test {

public static void main(String[] args) {

new PrintThread().start();

}

}

执行结果是:

输出一行字

这两种执行任务的方法说不上谁好谁坏,但是使用继承Thread类并且覆盖run方法的方式把线程和任务给弄到了一块儿了,不可分割了,也就是所谓的耦合了,所以我们平时更倾向于使用任务和线程分开处理的第1种执行任务的方式。当然,有时候为了演示的方便,也是会使用继承Thread类并且覆盖run方法的方式~

线程相关方法

Thread类提供了许多方法来方便我们获取线程的信息或者控制线程,下边来一下都有哪些重要的方法吧:

获取线程ID

long getId():系统会为每个线程自动分配一个long类型的id值,通过getId方法可以获取这个值。

System.out.println(new Thread().getId());

System.out.println(new Thread().getId());

System.out.println(new Thread().getId());

执行结果:

10

11

12

获取和设置线程名称

void setName(String name):设置线程的名称。

String getName():获取线程的名称。

当然,我们也可以通过构造方法去设置Thread的名称:

Thread t1 = new Thread("t1");

Thread t2 = new Thread();

t2.setName("t2");

System.out.println("t1线程的名称是:" + t1.getName());

System.out.println("t2线程的名称是:" + t2.getName());

执行结果是:

t1线程的名称是:t1

t2线程的名称是:t2

设置线程的优先级

我们知道处理器会从就绪的队列里挑一个已经就绪的线程去执行,每个线程都可以有不同的优先级,优先级越高,越容易被处理器选中执行。

void setPriority(int newPriority):设置线程优先级。

java中的优先级是用一个正数来表示,共有1~10个等级,其中,设计java的大叔们用了是三个静态变量表示我们常用的:

Thread.MIN_PRIORITY = 1;

Thread.NORM_PRIORITY = 5;

Thread.MAX_PRIORITY = 10;

一般情况下,我们就用这三个变量去表示优先级就够用了。

int getPriority():获取线程的优先级

下面看个例子:

Thread t1 = new Thread("t1");

System.out.Println("t1线程的优先级是:" + t1.getpriority());

t1.setPriority(Thread.MAX_PRIORITY);

System.out.Println("t1线程的优先级是:" + t1.getpriority());

注意:线程优先级并不意味着得不到处理器执行,而只是执行的频次低一点而已。而且线程的优先级一般不用我们主动去设置,所以这两个方法对我们来说基本没啥用~

休眠

如果想在线程执行过程中让程序停一段时间之后再执行,这个停止一段时间也叫做休眠,就好像睡一段时间然后醒来。可以通过sleep()方法来实现休眠:

static void sleep(long millis) throws InterruptedException

程序在指定的毫秒数加纳秒数内让当前正在执行的线程休眠,也就是暂停执行。

static void sleep(long millis, int nanos) throws InterruptedException

程序在指定的毫秒数加纳秒数内让当前正在执行的线程休眠,也就是暂停执行。

大家注意到这个sleep方法是一个静态方法,它会让当前线程暂停指定的时间。这个所谓的暂停,或者说休眠其实只是把正在运行的线程阻塞掉,放到阻塞队列里,等指定的时间一到,再从阻塞的队列里出来而已。另外,这个方法有InterruptedException的异常,说明我们在调用的时候需要catch一下:

public static void main(String[] args) {

System.out.println(1);

try {

Thread.sleep(1000L);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

System.out.println(2);

try {

Thread.sleep(1000L);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

System.out.print(3);

}

大家在执行的过程中会发现,每隔一秒会输出一个数字。另外,由于是在main方法中调用的sleep方法,所以其实休眠的是main线程,大家可以试试在自己的线程里休眠哈~

让出本次处理器的时间片

我们知道线程是处理器时间片的分配单位。不同的线程排着对等着处理器赏赐给一个时间片用来执行一会儿代码。如果一个线程已经获得了一个时间片正在执行,它突然不想执行了,可以放弃此次的时间片时间,先让处理器给别的线程分配一个时间片,而他参与下一轮的时间分配。

举个例子:比如说我们把处理器比作皇帝,把各个线程比作妃子,各个妃子争相让皇帝宠幸,为了公平,皇帝只能一次宠幸一个妃子五分钟。皇帝怎么挑选妃子有他自己的小算盘,但是,每个五分钟都会选一个去陪她。此时有一个妃子被皇帝挑选中了,可是她配了皇帝五分钟有些尿急,所以她主动说先放弃这次宠幸,先出去放放水,然后再排队被挑选吧。所以只陪了皇帝两分钟的她便退出了此次宠幸,放水回来后再加入到覅诶这大军中等待皇帝挑选。

static void yield():表示放弃此次时间片时间,等待下次执行。

这个yield方法只是建议处理器不要在此次时间片时间内继续执行本线程,最后实际怎么着还不一定呢,另外,yield是一个静态方法,表示让出当前线程本次时间片的时间。

也就是说你想放弃就放弃是不可能的,这还得看皇帝的心情~

java 线程概念_java并发编程之 java线程基本概念相关推荐

  1. java futuretask 状态_java并发编程之FutureTask

    引言 FutureTask实现了接口Future,同Future一样,代表异步计算的结果.当然,FutureTask除了实现Future接口之外,还实现了Runnable接口,所以,FutureTas ...

  2. 并发编程之 Executor 线程池原理与源码解读

    并发编程之 Executor 线程池原理与源码解读 线程是调度 CPU 资源的最小单位,线程模型分为 KLT 模型与 ULT 模型,JVM使用的是 KLT 模型.java线程与 OS 线程保持 1:1 ...

  3. java 时间戳_Java并发编程之CAS三CAS的缺点 及解决办法

    Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...

  4. java并发编程_Java并发编程之 synchronized

    大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈).上次老师跟大家分享了下Java中内存泄漏如何分析解决的相关知识,今天跟大家分享Java之 sync ...

  5. JUC并发编程之Java线程(二)

    二.Java线程 2.1 创建和运行线程 方法一:Thread创建线程方式: 继承Thread类 匿名内部类方式 public class CreateThread01 {public static ...

  6. Java并发编程之Java线程池

    Java线程池: 线程池的核心配置参数: //线程等待任务的超时时间,当线程池的线程个数超过corePoolSize时生效,当线程等待任务的时间超过keepAliveTime时,线程池会停止超过cor ...

  7. 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则

    前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...

  8. 并发编程之Java内存模型

    在介绍Java内存模型之前,先来了解一下为什么要有内存模型,以及内存模型是什么.然后我们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性. 为什么要有内存模型 在计算机中,所有的运算操 ...

  9. java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂

    引言 通过前面的文章,我们学习了Executor框架中的核心类ThreadPoolExecutor ,对于线程池的核心调度机制有了一定的了解,并且成功使用ThreadPoolExecutor 创建了线 ...

  10. 并发编程之Executor线程池原理与源码解读

    1. 线程池 "线程池",顾名思义就是一个线程缓存,线程是稀缺资源,如果被无限制的创建,不 仅会消耗系统资源,还会降低系统的稳定性,因此Java中提供线程池对线程进行统一分配. 调 ...

最新文章

  1. IPython 更改默认字体大小
  2. 【AWS 安全系列】Amazon S3 配置错误(下)
  3. git回退分支提交代码
  4. 【CF 应用开发大赛】JEECG 基于代码生成器J2EE智能开发框架
  5. 东莞新能源——业务流程管理实践
  6. 2019-03-15-算法-进化(有效的数独)
  7. UVA 12298——Super Poker II
  8. IPMSG飞鸽传书3——协议翻译
  9. oracle学用命令大全 笔记
  10. tcp连接python_python网络编程--TCP连接的三次握手(三报文握手)与四次挥手
  11. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_11-修改页面-前端-Api调用...
  12. Win10 技巧:让任务栏时间显示 “秒”
  13. 并发编程学习之生产者消费者模式 - 使用Condition实现
  14. uniapp 拍照 或者 相册 识别身份证信息
  15. x线计算机体层成像设备教案,医学影像设备学第4章-数字X线设备ppt课件
  16. mysql查找数据库文件位置
  17. 前端开发项目——企业员工管理系统(前后端分离)
  18. Python 函数的嵌套
  19. 迈普路由器访问控制列表配置命令_迈普路由器配置命令集合
  20. Win7 VirtualBox运行出现“0x00000000指令引用的0x00000000内存。该内存不能为written” ,错误解决

热门文章

  1. 数字图像处理第五章笔记
  2. 威斯敏斯特教堂(西敏寺)墓碑上的话(WestMinster Abbey,When I was young and free...,修身齐家治国平天下)
  3. to_param()函数和parameterize()函数
  4. ElementUI ===> 表单 rules 规则
  5. springside mysql_SpringSide4之SpringDataJpa测试
  6. 直接在pocket pc上编译c#程序
  7. python开三次方_用python计算三次方根
  8. ESXI VIB升级报错
  9. 网络公益信息特征和用户行为规律研究以微博为例
  10. 2021微信红包封面免费领取最新攻略 春节免费微信红包封面序列号大全