Java基础-线程与并发1
线程与并发 Thread
基本概念
程序: 一组计算机能识别和执行的指令 ,是静态的代码。
进程: 程序的一次运行活动, 运行中的程序 。
线程: 进程的组成部分,它代表了一条顺序的执行流。
进程线程联系:
① 线程是进程的最小执行和分配单元,不能独立运动,必须依赖于进程。众多的线程组成了进程。
② 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
进程线程区别:
① 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
② 并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
③ 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源
④ 系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,
导致系统的开销明显大于创建或撤消线程时的开销,所以使用多线程可以减小的资源开销
生命周期
新生状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态,
当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
创建线程的方法
继承Thread类
1.定义继承Thread的子类
2.子类重写Thread的run方法
3.实例化子类对象,创建线程
4.调用start方法,启动线程
源码
public class TestThread {
public static void main(String[] args) {
//创建线程方法1 继承Thread,重写run
NewThread thread = new NewThread();
thread.start();
System.out.println("主线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("主线程:"+i);
}
}
}
class NewThread extends Thread{
@Override
public void run() {
System.out.println("分支线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("分支线程:"+i);
}
}
}
运行几次程序,发现控制台得到的结果是不一样的。这就是cpu调度的随机性。
实现Runnable接口
1.定义实现Runnable接口的子类
2.子类实现Runnable的run方法
3.通过Thread的类构造器创建线程对象
4.将Runnable实例做为实参传给构造器
5.调用Thread实例的start方法,启动线程
源码
public class TestThread {
public static void main(String[] args) {
//创建线程方法2 实现Runnable接口
Thread thread = new Thread(new NewRunnable());
thread.start();
System.out.println("主线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("主线程:"+i);
}
}
}
class NewRunnable implements Runnable {
@Override
public void run() {
System.out.println("分支线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("分支线程:"+i);
}
}
}
两种创建方法的区别
- 采用实现 Runnable接口的方式创建多线程时,线程类只是实现了 Runnable 接口,还可以继承其他类。(推荐)
- 多个线程可以共享同一个Runnable实现类的对象,利于资源同步。
- 使用继承 Thread 类的方式创建多线程时,如果需要访问当前线程,直接使用 this 即可获得当前线程。
Thread类
构造方法
常用方法
方法 | 功能描述 |
---|---|
public void start() | 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。 |
public void run() | 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。 |
public final void setName(String name) | 改变线程名称,使之与参数 name 相同。 |
public final void setPriority(int priority) | 更改线程的优先级。 |
public final void setDaemon(boolean on) | 将该线程标记为守护线程或用户线程。 |
public final void join(long millisec) | 等待该线程终止的时间最长为 millis 毫秒。 |
public void interrupt() | 中断线程。 stop()已过时。 |
public final boolean isAlive() | 测试线程是否处于活动状态。 |
public final synchronized void join(long millis) | 等待该线程终止的时间最长为 millis 毫秒 |
public static void yield() | 线程让步,暂停当前正在执行的线程对象,并执行其他线程。 |
public static void sleep(long millisec) | 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。 |
public static Thread currentThread() | 返回对当前正在执行的线程对象的引用。 |
优先级
/** * The minimum priority that a thread can have. */
public final static int MIN_PRIORITY = 1;
/** * The default priority that is assigned to a thread. */
public final static int NORM_PRIORITY = 5;
/** * The maximum priority that a thread can have. */
public final static int MAX_PRIORITY = 10;
范围1-10,数字越大系统调用的概率越高。默认优先级为5。
实例测试代码
public class FunctionTest {
public static void main(String[] args) throws InterruptedException {
Thread threadChild = new NewThread();
Thread threadRun = new Thread(new NewRunnable(),"线程2 ");
//先设置优先级
threadChild.setPriority(1);
threadRun.setPriority(10);
//启动线程
threadChild.start();
threadRun.start();
//获取线程属性
threadChild.setName("线程1 ");
System.out.println(threadChild.getName());
System.out.println(threadRun.getName());
System.out.println(Thread.currentThread().getName());
if (threadChild.isAlive())
System.out.println(threadChild.getName()+"活着");
System.out.println("------有人在中间插队------");
threadChild.join();//执行完毕才到下一行
System.out.println("------有人在中间插队------");
//打印线程状态
threadRun.interrupt();
System.out.println(threadChild.isAlive());
System.out.println(threadRun.isAlive());
}
}
后记
以上内容仅仅是很基础的概念认识。
实际应用中会遇到很多问题,比如:
- 线程同步
- 线程间通信
- 线程死锁
- 线程控制:挂起、停止和恢复
Java基础-线程与并发1的更多相关文章
- Java基础-线程安全问题汇总
Java基础-线程安全问题汇总 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存泄漏和内存溢出(out of memory)的区别 1>.什么是内存溢出 答:内存溢出指 ...
- Java基础-线程操作共享数据的安全问题
Java基础-线程操作共享数据的安全问题 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.引发线程安全问题 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运 ...
- Java基础——线程总结
Java基础--线程总结 一.线程是什么? 线程:一个程序里不同的运行路径. 二.怎样创建线程? 两种方法创建线程: 第一种 (1)定义详细功能类实现Runnable接口,能够多次调用而实现数据共享 ...
- 《Java基础——线程类》
Java基础--线程类 一.线程的创建之Thread类: 规则: 通过声明一个新类作为子类继承 Thread 类,并复写 run() 方法,就可以启动新线程并执行自己定义的 run()方法 ...
- JAVA基础—线程池
推荐文章java多线程基础 线程池概述 为什么要使用线程池 1.服务器创建和销毁工作线程的开销很大 2.如果频繁的创建和销毁线程会导致频繁的切换线程,因为一个线程被销毁后,必然要把CPU转让给另一个已 ...
- Java基础 - 线程(一)
一.什么是线程 首先,介绍一下线程.进程的概念. 进程是操作系统分配资源的最小单元,线程是操作系统调度的最小单元.进程是指运行中的应用程序,Windows任务管理器进程窗口看到的每一项都是一个进程.每 ...
- java基础—线程(一)
一.线程的基本概念
- 图学java基础篇之并发
概述 并发处理本身就是编程开发重点之一,同时内容也很繁杂,从底层指令处理到上层应用开发都要涉及,也是最容易出问题的地方.这块知识也是评价一个开发人员水平的重要指标,本人自认为现在也只是学其皮毛,因此本 ...
- Java基础--线程创建方式
线程的创建主要有两种形式,通过继承Thread或者实现Runnable接口,本质上没有太大区别. /** * @date: 2019/7/16 **/ public class ThreadOne i ...
随机推荐
- Centos6,Centos7防火墙设置与端口开放的方法
Centos升级到7之后,内置的防火墙已经从iptables变成了firewalld.端口的开启还是要从两种情况来说明的,即iptables和firewalld. 一.iptables 1.打开/关闭 ...
- .NET Core加解密实战系列之——RSA非对称加密算法
目录 简介 功能依赖 生成RSA秘钥 PKCS1格式 PKCS8格式 私钥操作 PKCS1与PKCS8格式互转 PKCS1与PKCS8私钥中提取公钥 PEM操作 PEM格式密钥读取 PEM格式密钥写入 ...
- 关于Api的那些事儿!
工作中一直在写Api数据接口,但大部分的Api都存在这样的问题 1.接口请求的地址和参数暴露 2.重要接口返回数据明文暴露 3.APP登录态请求的数据完全性问题 4.代码层的数据完全性问题(从代码层有 ...
- 迷宫城堡+算法讲解【tarjian算法】
Tarjan 算法 参考博客:https://www.cnblogs.com/shadowland/p/5872257.html 算法讲解 Tarjan 算法一种由Robert Tarjan提出的求解 ...
- MSSQL2008下备份好的*.bak--->>>恢复到--->>>MSSQL2014(解决办法)
MSSQL2008下备份好的*.bak--->>>恢复到--->>>MSSQL2014(解决办法) 在进行CTE训练时(同时也要理解下窗口函数的应用),发现不能继续 ...
- RESTORE FILELISTONLY FROM DISK ='D:\DataSQL\BakFile\pubs.bak' _ 数据库安装工具_连载_4
在查询分析器中执行: RESTORE FILELISTONLY FROM DISK = 'D:\DataSQL\BakFile\pubs.bak'根据查询类型判断Type(D.L),再取得对应的Lo ...
- 关于Ubuntu系统忘记密码的解决方法合集
昨天有台机器的Ubuntu系统密码出了问题,一直提示错误.由于里面的数据比较重要,不建议重装系统,所以百度了一会,最终解决了忘记密码问题.整理了一个大合集分享出来. 第一种:参考教程如下 ...
- C++中为什么按两次ctrl+D才能结束标准I/O
参考资料: https://www.douban.com/group/topic/127062773/ 今天学习了C++语言的标准I/O,也就是std::cin和std::cout,但是我发现当系统在 ...
- Beta冲刺<1/10>
这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺--第一天(05.19) 作业正文 如下 其他参考文献 ... B ...
- Azure Monitor(一)Application Insights
一,引言 Azure Monitor 是 Azure 中的一项完整堆栈监视服务,是一种收集和分析遥测数据的服务.它提供了一组完整的功能来监视 Azure 资源以及其他云中和本地的资源.Azure Mo ...