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 ...
随机推荐
- 倍增法求LCA代码加详细注释
#include <iostream> #include <vector> #include <algorithm> #define MAXN 100 //2^MA ...
- android在service中stopself遇到的问题
在service的oncreate中直接调用stopservice停止自己,依然会执行onstartcommand方法后,最后才调用ondestory方法
- Markdown 主题修改
加粗字体的颜色修改 strong, b{ color: #111111; } 斜体的颜色修改 em, i { color: #111111; } 高亮字体的背景颜色修改 #write mark { b ...
- @bzoj - 3148@ 没头脑和不高兴
目录 @description@ @solution@ @part 1:期望@ @part 2:方差@ @accepted code@ @details@ @description@ 没头脑和不高兴是 ...
- Python:列表和列表的增删改查
目录 列表 列表的取值 通过下标 切片 用len()取得列表的长度 用下标改变列表中的值 列表连接和列表复制 用 del 语句从列表中删除值 in和not in操作符 多重赋值 列表的方法 查找 增加 ...
- pip 安装使用国内镜像
pip国内的一些镜像 阿里云 https://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple ...
- JS之预解释原理
预解释的原理 预解释的不同机制 var的预解释机制 function 的预解释机制 预解释机制 面试题练习 预解释的的不同机制 预解释也叫预声明,是提前解释声明的意思:预解释是针对变量和函数来说的:但 ...
- JS遍历对象的几种方法
几天前一个小伙伴问我 Object.getOwnPropertyNames() 是干什么用的 平时还真没有使用到这个方法,一时不知如何回答 从方法名称来分析,应该是返回的是对象自身属性名组成的数组 那 ...
- mysql常用基础指令大全
mysql指令 启动 net start mysql 退出mysql quit 登录 mysql -uroot -p 逻辑非 not ! 逻辑与 and && 或者 or || 逻辑异 ...
- gdb基本命令总结
本文介绍使用gdb调试程序的常用命令. 主要内容: [简介] [举例] [其他] [简介] ============= GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.如果你是在 ...