Java高并发入门-线程初步

线程与进程之间的关系

进程就是我们运行在计算机上的一个程序,对应Java程序来说就是运行在计算机上的Java应用程序,这个程序在运行的时候就会创建了一个进程,服务器上就会存在一个Java进程。而对于线程来讲,线程是运行在进程里面。为了执行一条具体任务。比如说一个人同时可以做两件时间,同时听音乐或者看电视等操作。单线程的程序来说就只能等到某个线程执行完毕之后才会执行下一个线程任务。不会存在多个线程之间竞争的问题,但是这样的单线程的执行效率比较低。

Java 实现多线程的方式有几种

  • 实现Runnable接口
  • 继承Thread类
  • 实现Callable接口

- 实现Runnable接口的方式

   private static class TestDemo implements Runnable{private int count = 1;@Overridepublic void run() {System.out.println(count++);}}public static void main(String[] args) {TestDemo testDemo = new TestDemo();Thread thread = new Thread(testDemo);Thread thread1 = new Thread(testDemo);thread.start();thread1.start();testDemo.run();//count的值//1 2   2 1  2 2   1 1}

同这个例子可以判断一下count的值是多少。这里也为后面锁竞争问题的关键点。

蓝色代表我们主线程,红色代表创建两个线程,由于Count是一个共享资源所以在访问的时候会出现锁竞争的问题,如图所示,主线程直接执行,而两个线程由于要进行锁竞争,会出现第一个线程先抢占Count资源然后进行加一操作,第二个线程抢占资源之后就是加一后的值。

-继承Thread类

private static class Demo extends Thread{private int count = 1;@Overridepublic void run() {System.out.println(count++);}}public static void main(String[] args) {new Demo().start();new Demo().start();System.out.println("==========******==============");Demo demo = new Demo();demo.start();System.out.println("=======================");Demo demo1 = new Demo();Thread thread = new Thread(demo1);thread.start();}

分析代码

  1. 前两组是一个结果,中间是一个结果,最后是一组结果,三组结果有什么区别
  2. 这个就引出一个问题,锁竞争问题
  3. 第一组结果

    这个结果是怎么样输出的,首先因为Demo继承Thread所以说在输出的时候,肯定是实现了toString,由于Demo没有toString方法所以说只能在其父类中找到
public String toString() {ThreadGroup group = getThreadGroup();if (group != null) {return "Thread[" + getName() + "," + getPriority() + "," +group.getName() + "]";} else {return "Thread[" + getName() + "," + getPriority() + "," +"" + "]";}}

从这个方法中可以看到首先获取线程组,判断线程组是否为空,然后获取到线程组的名称,获取到线程组的运行级别进行输入。到这里可以发现两个结果,这个两个结果的线程名称不是同一个,运行级别相同,同属于Main线程组。
因为Demo继承了Thread类所以说与Thread类有相同方法。所以说可以当做一个线程来创建。为什么没有出现锁竞争问题,是因为,在这里我们创建两个不一样的线程,访问的两个不一样的资源,所以说没有出现锁竞争问题。如果在程序运行过程中,出现访问共享资源的情况就会出现锁竞争问题。

从图中可以看到这个红色代表两个匿名对象,而蓝色代表主线程。就是这样的一个关系图,由于两个匿名对象不是同一个对象,所以说没有没有出现锁竞争问题,第二组是与第一组类似而第三组

  Demo demo1 = new Demo();Thread thread = new Thread(demo1);thread.start();

这个方法看上去是比较繁琐的,本来可以直接启动的,却使用了新的Thread对象来进行线程的创建,而这三种方式有什么区别。为了判断这三种方式的正确性我们分析一下Thread的源码。

API推荐方式

 class PrimeThread extends Thread {long minPrime;PrimeThread(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}}PrimeThread p = new PrimeThread(143);
p.start();

这个创建与使用与上面我们的创建与使用是类似。
进入Thread源码首先是一个无参构造函数调用init方法

 public Thread() {init(null, null, "Thread-" + nextThreadNum(), 0);}
private void init(ThreadGroup g, Runnable target, String name,long stackSize) {init(g, target, name, stackSize, null, true);}
private void init(ThreadGroup g, Runnable target, String name,long stackSize) {init(g, target, name, stackSize, null, true);}private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals) {if (name == null) {throw new NullPointerException("name cannot be null");}this.name = name;Thread parent = currentThread();SecurityManager security = System.getSecurityManager();if (g == null) {if (security != null) {g = security.getThreadGroup();}if (g == null) {g = parent.getThreadGroup();}}g.checkAccess();if (security != null) {if (isCCLOverridden(getClass())) {security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);}}g.addUnstarted();this.group = g;this.daemon = parent.isDaemon();this.priority = parent.getPriority();if (security == null || isCCLOverridden(parent.getClass()))this.contextClassLoader = parent.getContextClassLoader();elsethis.contextClassLoader = parent.contextClassLoader;this.inheritedAccessControlContext =acc != null ? acc : AccessController.getContext();this.target = target;setPriority(priority);if (inheritThreadLocals && parent.inheritableThreadLocals != null)this.inheritableThreadLocals =ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);/* Stash the specified stack size in case the VM cares */this.stackSize = stackSize;tid = nextThreadID();}

什么是锁竞争?

在多线程编程过程作用,会遇到多个线程访问同一个资源的情况,这个资源有可能是方法,类,成员变量等等,这个时候就会出现多个线程同时要去使用这个资源才能够继续运行,就会出现过个线程争抢同一个资源的情况。把这种情况就可以称为锁竞争。

Java高并发入门-线程初步相关推荐

  1. Java高并发入门-线程初步(二)

    Java高并发入门详细讲解 上期回顾及问题总结 上次说了创建线程的两种常用方式,第三种方式在后面的更新中会讲解到.这里对于上一节的内容做个回顾. 在上一节中说到了创建多线程的问题,分析了Thread的 ...

  2. java queue 线程安全_详解Java高并发——设计线程安全的类

    前言: 将现有的线程安全的组件组合为更大规模的组件或程序. 通过使用封装技术可以使得在不对整个程序进行分析的情况下就可以判断一个类是否是线程安全的. 一. 基本要素 1. 找出对象状态的所有变量 如果 ...

  3. Java高并发编程详解系列-Java线程入门

    根据自己学的知识加上从各个网站上收集的资料分享一下关于java高并发编程的知识点.对于代码示例会以Maven工程的形式分享到个人的GitHub上面.   首先介绍一下这个系列的东西是什么,这个系列自己 ...

  4. [Java高并发系列(5)][详细]Java中线程池(1)--基本概念介绍

    1 Java中线程池概述 1.1 什么是线程池? 在一个应用当中, 我们往往需要多次使用线程, 这意味着我们需要多次创建和销毁线程.那么为什么不提供一个机制或概念来管理这些线程呢? 该创建的时候创建, ...

  5. Java高并发程序设计入门

    转自:http://blog.csdn.net/johnstrive/article/details/50667557 说在前面 本文绝大部分参考<JAVA高并发程序设计>,类似读书笔记和 ...

  6. java高并发系列 - 第6天:线程的基本操作,必备技能

    新建线程 新建线程很简单.只需要使用new关键字创建一个线程对象,然后调用它的start()启动线程即可. Thread thread1 = new Thread1(); t1.start(); 那么 ...

  7. Java并发编程实战_阿里P9整理分享的亿级流量Java高并发与网络编程实战PDF

    前言 为了帮助初级开发者快速掌握高并发.网络编程.微服务.海量数据的处理这些实用技术,本文以"理论+范例"的形式对各个知识点进行了详细的讲解,力争让读者在实践中快速掌握相关知识. ...

  8. 阿里P9整理分享的亿级流量Java高并发与网络编程实战PDF

    前言 有人调侃我们说: 程序员不如送外卖.送外卖是搬运食物,自己是搬运代码,都不产出新的东西-- 透支体力,又消耗健康,可替代性极强,30岁之后就要面临被优化的危险-- 想跳槽,但是更高的平台难进,同 ...

  9. cpu高 thread vm_阿里大佬总结,Java高并发必读!

    作者:wxdoop 原文:https://blog.csdn.net/qq_36235098 来源:前程有光 前言 进程是计算机中程序关于某几何数据集合上的一次运行活动,是系统进行资源分配和调度的基本 ...

最新文章

  1. IntelliJ IDEA 2020.2.4款 神级超级牛逼插件推荐
  2. 前端基础--jquery操作元素
  3. window 桌面开发_C#桌面开发的未来WebWindow
  4. 聚合中返回source_Java 8 中的 Streams API 详解—— Streams 的背景以及 Java 8 中的使用详解...
  5. 3.6 Git 分支 - 变基
  6. Linux下系统函数open,read,write,lseek函数
  7. TypeScript里对数组元素的自定义属性排序的实现原理
  8. 一些难懂的笑话,看看你懂得多少? [转帖]
  9. 【Elasticsearch】elasticsearch 查询 高亮
  10. 洛谷P2585 [ZJOI2006]三色二叉树
  11. HTTP协议与HTTPS的区别
  12. 华人运通高合HiPhiX维修手册电路图技术培训用户手册资料
  13. iPhone防止系统自动下载更新
  14. linux 实现离线迅雷,Linux下使用wget/aria2进行离线迅雷批量下载
  15. 优秀的程序员应该具备哪些素质
  16. leetcode1055
  17. 书家必备——容易寫錯用錯的繁體字一百例
  18. 计算机组成原理 总线与微命令实验
  19. 宝塔面板+腾讯云轻量应用服务器部署fiora聊天室
  20. android 9.0的模拟器,exagear模拟器最新版安卓9.0

热门文章

  1. vue点击input框出现弹窗_vue组件实现弹出框点击显示隐藏效果
  2. 一个题目涉及到的50个Sql语句
  3. 看透设计模式-行为型模式
  4. consul代理---健康检测
  5. 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(2)
  6. FMDB(FMDatabase)--SQLite的封装
  7. javascript的一些基本概念
  8. Activity 之生命周期
  9. 为 Confluence 6 配置发送邮件消息
  10. Word2013中制作按钮控件