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 ...
随机推荐
- Java实现第八届蓝桥杯最大公共子串
最大公共子串 最大公共子串长度问题就是: 求两个串的所有子串中能够匹配上的最大长度是多少. 比如:"abcdkkk" 和 "baabcdadabc", 可以找到 ...
- FTP服务器上传工具,FTP服务器上传工具下载!
IIS7服务器管理工具能够作为FTP的客户端,进行FTP的命令操作,可在客户端,下载,安装FTP软件! 同时,它也可以作为VNC的客户端,进行VNC的命令操作!它能够批量连接Windows和Linux ...
- Spring Boot 集成 Swagger 构建接口文档
在应用开发过程中经常需要对其他应用或者客户端提供 RESTful API 接口,尤其是在版本快速迭代的开发过程中,修改接口的同时还需要同步修改对应的接口文档,这使我们总是做着重复的工作,并且如果忘记修 ...
- 第一章03-Activity的启动模式
Activity的LaunchMode Android中提供了四中Activity的启动模式 1. standard 2. singleTop 3. singleTask 4. signleInsta ...
- web静态页面资源访问路径问题
我使用的是idea,今天搭建一个项目时遇见了css和js路径错误,导致浏览器获取不到资源路径 这是我最开始写的路径 <link href="/main/loginMain.css&qu ...
- vj提交时常见问题
- 宝塔面板如何有效的清除SSL证书以及缓存
一:关闭SSL 我们先关闭SSL证书,这个大家都会的吧.如图: 二:证书夹 网站配置的证书夹,我们删除掉,如图: 三:寻找SSL证书路径 网站配置里有一路径我们看下:如下 ssl_certificat ...
- IOS 发布 程序截图问题
特别要注意那个有无状态栏时的像素要求 **注意:在截屏模拟器的时候,请把模拟器的Scale设置成100%(Window->Scale->100%) 开模拟器截图,运行每一个iOS型号,然后 ...
- conda 切换为国内源
添加清华源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda con ...
- vue cli3项目中使用qrcodejs2生成二维码
组件的形式创建 1.下载依赖 npm install qrcodejs2 2.创建一个.vue的组件放置代码(我创建的是qrcodejs2.vue) //template中的代码 <templa ...