Java线程通俗讲解
Java线程介绍
通常情况下,在一个服务器上面运行的程序是很多的,可能同一时间会有多个客户
端的程序访问服务器,服务器都要对这些客户端做出响应。如果我们处理器有限,
只有一个处理器的时候,如何能够让这些任务看起来是并行的同时执行呢?这里就需要用到线程的知识。
当有超过一个以上执行空间时,看起来会像是有好几件事同时发生。但实际上,只有真正的多处理器系统才可以同时执行好几件事。使用java多线程可以让它看起来好像同时都在执行,也就是说,执行的动作可以在执行空间中快速切换,因此感觉上好像是每一个任务都在同时执行。在Java中,我们用Thread这个类来实现这一点。
下面我们通过代码一起来看一下如何新建一个线程(ThreadTest)。首先,我们需要新建一个Runnable对象。稍后我们会再定义Runnable类。而这个类会定义线程会执行什么样的任务。之后,我们会定义Thread对象,用它来去执行Runnable定义好的任务。然后,启动Thread,将Runnable对象的方法摆到新的执行空间中。
package web_server;public class ThreadTest {public static void main(String[] args) {// 新建Runnable对象Runnable threadJob = new MyRunnable();// 将Runnable的实例传给Thread的构造函数Thread myThread = new Thread(threadJob);// 调用start()才会让线程开始执行,在此之前// 它只是Thread一个实例,并不是真的线程myThread.start();System.out.println("back in main");}}
接下来我们再看如何实现Runnable。Runnable是一个接口,该接口只有一个方法,就是public void run()。在run中定义要执行的方法。因为Runnable是一个接口,线程的任务是可以被定义在任何实现Runnable的类上。线程只在乎传入给Thread的构造函数的参数是否为实现Runnable的类。当你把Runnable传给Thread的构造函数时,实际上就是在给Thread取得run的办法,这就等于你给Thread一项任务。
package web_server;public class MyRunnable implements Runnable{// Runnable接口只有一个方法,就是public void run()public void run() {go();}public void go() {doMore();}public void doMore() {System.out.println("top o' the stack");}
}
线程的原子性
每一个线程变成可执行状态之后,它就会在可执行和不可执行两种状态中来来回回的切换,有的时候也会出现第三种状态,就是暂时不可执行状态。现在假设你有多个线程在排队等待执行,这时候哪个线程先执行,具体执行多长时间呢?这些工作都由调度器来实现。线程调度器会去决定哪个线程跑起来,而哪个线程会暂时不去执行。
但是这样又会有一个大问题,特别是对于多线程而言,可能会发生a线程执行一段时间,然后b线程再执行一段时间。如果a线程和b线程的程序方法互不影响还好,如果a线程和b线程使用的是同样的程序方法,可能会发生结果互相影响的问题。对于这样的问题,我们可以通过Synchronized来解决。Synchronized关键字代表线程需要一把钥匙来存取被同步化过程的线程。也就是说,通过synchronized同步化修饰过后的方法,会将方法中的内容执行完之后,再交给别的线程去执行。如果想要保护重要的数据,就把作用在数据上的方法给同步化。这部分程序,不可分割,应该被连续的执行。在古典物理学中,我们认为原子是不可分割的最小物理单元。因此我们说synchronized修饰过的方法具有原子性。我们下面通过一个例子一起来看一下。
package web_server;public class TestSync implements Runnable{private int balance = 0;public void run() {for(int i = 0; i < 50; i++) {increment();System.out.println("balance is " + balance);}}public void increment() {// public synchronized void increment() {int i = balance;balance = i + 1;}}
package web_server;public class TestSyncTest {public static void main(String[] args) {// TODO Auto-generated method stubTestSync job = new TestSync();Thread a = new Thread(job);Thread b = new Thread(job);a.start();b.start();}}
可以看到,使用synchronized之后执行的效果看起来很正常,而不加之后有一些怪异的值。我们这里新建了两个线程,这两个线程执行的都是同样的方法。之所以不适用synchronized会出现数字乱的问题在于,比如说执行了i=balance之后,a线程就切换成b线程去执行了。还没有来得及累加。B线程执行一段时间之后再切换成a线程,然后a线程再继续累加,就会出现数字错乱的问题。而使用synchronized会让其强制执行完累加之后再去切换线程,所以不会出现错乱。
最后附上 本文内容对应的视频讲解
参考资料
《Head First Java》
Java线程通俗讲解相关推荐
- Java多数据源最通俗讲解
Java多数据源最通俗讲解 before after 理论 实操 编码 小总结 before 项目中可能会用到很多的数据源,例如目前这个项目中用到了五个数据源,那么数据源的 配置和数据源的切换就成为了 ...
- Java线程同步学习,线程不安全案例讲解,同步方法和同步块 synchronized
本文主要是自己学习多线程时,所做的笔记,参考的是b站狂神说Java多线程视频讲解. 目录如下: 文章目录 线程同步 一.三大线程不安全案例 1.买票案例 2.不安全取钱 3.线程不安全 二.同步方法及 ...
- Java线程的6种状态及切换(透彻讲解)
Java中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法. 2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running ...
- 网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?
1.前言 标题虽然是为了解释有了 IP 地址,为什么还要用 MAC 地址,但是本文的重点在于理解为什么要有 IP 这样的东西.本文对读者的定位是知道 MAC 地址是什么,IP 地址是什么. (本文同步 ...
- 蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)
前言:蓝牙聊天App设计全部有三篇文章(一.UI界面设计,二.蓝牙搜索配对连接实现,三.蓝牙连接聊天),这篇文章是:三.蓝牙连接聊天. 课程1:Android Studio小白安装教程,以及第一个An ...
- 第二十三章 Java线程与操作系统关系
Java线程与操作系统关系 Java线程的实现方式 线程的实现 内核线程实现 用户线程实现 用户线程加轻量级进程混合实现 Java线程的实现 Java线程调度 线程状态转换 线程安全 线程安全分类 线 ...
- Java线程状态完全解析教程
简介 Java线程有6种状态,分别是NEW.RUNNABLE.BLOCKED.WAITING.TIMED_WAITING.TERMINATED.本文讲解线程状态变化的流程以及用代码演示通过调用哪些方法 ...
- Java线程池面试必备:核心参数、工作流、监控、调优手段
欢迎关注方志朋的博客,回复"666"获面试宝典 1. Java的线程池 ① 合理使用线程池的好处 Java的线程池是运用场景最多的并发框架,几乎所有需要异步或者并发执行任务的程序都 ...
- Java线程池实现原理及其在美团业务中的实践
来自:美团技术团队 随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流.使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器.J.U.C提供的线程池ThreadPoolExecuto ...
最新文章
- 如何使用Next.js创建动态的Rick and Morty Wiki Web App
- SpringBoot整合Swagger测试api构建
- PageRequestManagerServerError
- PHP开发绝对不能违背的安全铁则!
- GitLab CI/CD
- android日常开发60条经验
- 前后端开发的心得体会_社招后端三面总结以及学习经验感言(操详细)
- Node连接MySQL数据库进行基本的增删改查操作(一看就会)
- SQL Server DATEPART() 函数
- 【mmdetection3d】——学习配置文件
- chrome源代码下载 编译 linux,源代码编译chrome os
- 完结!视频课程:CMOS模拟集成电路设计
- 双指缩放canvas图片_JS实现移动端双指缩放和旋转方法
- 制造业执行系统MES 在汽车零配件行业展露锋芒
- vasp能装在window系统里吗_Window安装系统详解
- 虾皮API接口—获取商品详情
- A ConvNet for the 2020s
- 【状语从句练习题】连词 + 过去分词
- Uniswap V3流动资金池遭遇网络钓鱼攻击,已损失价值3278ETH的NFT头寸,约合3563644美元。
- 手把手教你实现聚光灯效果