----进程和线程-----
1.概述:简单理解一个进程就是一个正在运行的程序(程序在内存中的所属空间)
程序只有在运行的时候才会被加载进内存
2.进程内部的划分
进程不会直接执行,只是被当作分配内存资源的基本单位,真正的执行单位就是线程(执行路径),一个进程至少含有一个线程,多个线程就代表多个任务,多个执行路径,可以并发运行,所以它们之间存在一定的制约条件 eg:可能存在多个线程合作完成某个任务,可能访问资源存在顺序关系。加载程序代码进内存--从某个入口执行
3.多线程存在的意义:并发执行,一段时间内可以同时执行多个任务
注意:并发并没有同时执行多个任务,微观串行,宏观并行。CPU控制程序运行,负责调度线程的运行(分时间片调度线程执行--时间片很短)
假如存在两个CPU,此时能够做到真正的并行执行--缺点还是没有足够的内存
4.多线程的好处和弊端
优点:能够解决多个程序一段时间内的并发执行
缺点:多线程被CPU调度的等待时间加多
5.目前只有一个线程--主函数线程(必须依赖于线程的执行),堆里面出现垃圾,垃圾回收线程
JVM一开启就会启动多个线程eg:主线程,垃圾回收线程等
线程的任务执行完成,线程就结束了,JVM会等着所有线程结束,JVM才会退出
6.垃圾回收器并不会一遇到垃圾就回收,而是先判断堆内存的大小,根据内存大小决定是否进行堆内存回收
7.主线程--仅仅存在时候,程序只有一条执行路径,按照代码书写的顺序执行(方法调用还是一个线程),JVM判断没有其他内容就直接关闭进程
8.什么时候可能会想到使用多线程
A-->B-->C 按照该顺序,但是B事件此时需要的循环时间花费大,所以此时就自定义一个线程,用来完成C时间的执行

-----多线程具体学习-----底层的执行与系统相关(Thread里面的方法基本是与系统相关的本地方法)
注意:关于为什么要继承Thread类,而不是直接创建Thread类对象
原因是:创建线程为了创建执行路径,主线程其执行的任务都定义在main方法里面,自定义的线程其对应的任务应该定义在Thread类定义的run()方法里面,所以不同的线程必须要进行特殊的任务时候,必须重写run(),进而就必须继承Thread类。

-----如何创建一个线程------
* 继承Thread类(已经实现Runnable接口),重写run方法
创建Thread子类的对象,启动线程 对象.start()并告诉JVM自动调用对象的run()方法
注意:利用子类对象调用run()此时不是启动线程,而是方法调用
CPU调动线程是随机的,所以执行的结果就是随机的
getName()获取线程对象的名字
Thread.currentThread()获取当前运行线程对象的引用
* 多线程运行图解
创建启动一个线程---就创建一个单独的路径(相当于每个线程有在进程的内存空间里面占有固定的空间,线程执行完后释放空间)
eg:有3的线程名字分别为1,2,3,他们分别执行,他们各自执行自己的内容(假如)
假如主线程出现异常,自会自己不执行下去,并不会导致其他线程的执行状态发生改变
谁发生异常,那个线程就结束---用于分析多线程安全问题
-----什么时候使用多线程----
某个代码要被同时执行,比如打印循环--可以将这些代码的执行利用线程来实现
让该类继承Thread类,重写run(){被多次执行的代码}。
问题出现:假如该类以及继承一个父类,无法进行继承Thread类,可以采用第二种创建线程的方式。
* 定义类实现Runnable接口,重写run()方法,创建Thread对象接受Runnable接口的子类对象
(接口可以对类的功能进行扩展)
MyThread implements Runnable{
public void run(){线程体;}
}
MyThread mt = new MyThread();
Thread t = new Thread(mt);--存在多态 t.start();
第二种创建设计思想:持有接口的引用(调用第二种构造线程对象的构造方法)-看源码
第二种创建线程好处
* 在第一种方法中继承Thread()类,其实就是仅仅想使用run()方法,并没有想要继承Thread类里面的所有方法,此时我们就可以直接实现接口Runnable(只用重写一个run方法就可以了)
* 第二个好处在要执行多次的类已经有父类的情况下,选择实现接口--避免单线程局限性
所以创建线程的第二种方式比较常见
* Thread类也是实现了Runnable接口

------线程的状态转化-------
1.被创建状态---变成线程对象
2.调用start被启动成为就绪状态--等待CPU的调度-有被执行的资格
3.假如CPU调动--就变成运行状态--CPU正在处理该线程
(就绪--运行 运行--就绪 运行(等待事件的发生/自己调用sleep休眠一定的时间)--阻塞 阻塞(被别的对象唤醒)--就绪)通过对象调用wait/notify方法(Object里面的方法)
调用sleep()后会让出CPU的执行权,等醒来后,再继续在就绪队中排队等待调度
注意:sleep()在那个线程体里面,那个线程休眠
4.阻塞状态:释放执行权被CPU调度,放弃执行资格
5.线程死亡:线程被强制结束stop/线程体执行完了
6.线程启动后,不能重复启动---会发生异常

------多线程安全问题的引出------
四个卖票卖完--多线程同时执行--
1.方法一处理:继承Thread类,此时num会存在于4个线程对象中,总数400票
可以静态处理num--但是这不太符合题目的要求
2.方法2处理实现接口,但是只用创建一个Ticket对象,所以总数字就是100票
3.多线程安全问题产生的原因
* 多线程操作共享数据
* 操作共享数据的代码有多条
* 当一个线程在操作共享数据的多条代码中时候,又有其他线程参与其中,就会导致线程安全问题的产生
------多线程问题的解决办法-------
本质就是防止一个线程在操作共享数据的时候,另外没有其他线程的参与
具体的设计:
就是将多线程操作共享数据的代码封装起来,当有线程执行代码的时候,不允许其他的线程访问,只有当该线程执行完后,别的线程才可以访问。
1.对象锁synchronized修饰代码块--同步代码块--实现同步
具体格式synchronized(对象){需要被同步的代码;}
对象--this/其他任何对象
观察结果:只有部分线程打印--原因就是其他的线程未抢到被执行的机会
2.修饰方法--同步方法(需要被按照次序执行)---锁定的是该方法所属对象--也是一种封装
锁是方法所属对象--this
可以让线程1--使用同步代码块;线程2--使用同步方法,只要他们的锁定为同一个this,就可以实现线程1,2的同步:
注意:eg:卖票例子的具体实现过程:
1.创建2个卖票线程,以及本来就存在的主线程
2.主线程运行,启动线程1,主线程休眠让出cpu执行权,线程1获得执行权,持有this锁进入run方法里面,先休眠(该过程不会释放锁),醒来后继续执行(或者),cpu分配的时间片结束后,让出cpu执行权。
3.主线程修改Flag参数,线程2启动并获得执行可能执行到结束。

-----同步代码块与同步方法的区别-----
同步函数的对象锁---this
同步代码块的锁---可以为任意的对象
一般比较推荐使用同步代码块

----静态同步函数的锁----
静态同步函数的锁:所属类的字节码文件被封装的为Class类型的对象--字节码文件对象
获取该对象的方式:this.getClass()/Thicket.class(字节码文件对象具有静态属性class)

----同步使用的前提----
同步并不能解决所有的线程安全问题,它解决的是问题必须具备以下两点
1.程序中存在多个线程
2.保证多个线程访问同一个资源时候使用相同的锁,否则就不能保证某个线程在访问该资源的时候,没有其他线程的进入。
3.锁:其实本质就是保证线程在被CPU调度后,执行的过程中不会存在别的线程的进入
(不管任何任何情况--休眠/时间片用完等情况,只要是线程处在同步中,就会保证只有一个线程在其中--一旦出了同步其他线程在获得调度权的情况下,就可以进入同步中)
4.多个线程访问共享资源,有安全隐患,并不是每次都发生安全问题

---单例设计模式与多线程安全----
单例设计模式
1.懒汉式--延迟加载单例模式,先创建引用,调用get方法的时候,再创建对象--比较推荐
2.饿汉式--创建对象,提供返回该对象的公共的方法
3.对于懒汉式单例---加了同步方法,会每次都判断锁,费时间,所以加同步代码块,会先判断假如已经创建一个对象,不要判断锁,直接获取单例对象。

---死锁----
1.常见形式之一同步嵌套--线程A在具备a锁情况下,还需要b锁,同时线程B在具备b锁情况下,还需要a锁,俩个线程互不相让--导致两个线程都不能进行下去

Java基础总结--多线程总结1的更多相关文章

  1. Java基础技术多线程与并发面试【笔记】

    Java基础技术多线程与并发 什么是线程死锁? ​死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,我们就可以称 ...

  2. Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  3. 关于java基础、多线程、JavaWeb基础、数据库、SSM、Springboot技术汇总

    作者 : Stanley 罗昊 本人自行总结,纯手打,有疑问请在评论区留言 [转载请注明出处和署名,谢谢!] 一.java基础 1.多态有哪些体现形式? 重写.重载 2. Overriding的是什么 ...

  4. Java基础之多线程框架

    一.进程与线程的区别 1.定义: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比 ...

  5. Java基础之多线程详细分析

    在了解多线程之前,先来了解一下进程与线程之间的关系. 进程和线程: 进程是指在系统中正在执行的一个程序,每个进程之间是独立的. 线程是进程的一个基本执行单元.一个进程要想执行任务,必须得有线程(每1个 ...

  6. java基础知识 多线程

    package org.base.practise9; import org.junit.Test; import java.awt.event.WindowAdapter; import java. ...

  7. Java基础之多线程

    1.进程和线程: 进程:正在进行的程序.每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元. 线程:进程内部的一条执行路径或者一个控制单元. 两者的区别: 一个进程至少有一个线程 ...

  8. 黑马程序员——【Java基础】——多线程

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 (一)进程 正在执行中的程序,每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控 ...

  9. 黑马程序员——JAVA基础之多线程的线程间通讯等

    ------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...

  10. 黑马程序员——JAVA基础之多线程的安全问题

    ------- android培训.java培训.期待与您交流! ---------- 导致多线程出现问题的一个特殊的状态:就绪.具备了执行资格,但是还没有获取资源. 导致安全问题的出现的原因: 1. ...

随机推荐

  1. 市场主流5款HTML5开发框架详解

    我们经常听见的前端框架是一个非常大的范词,因为前端框架都是基于JS.CSS.HTML5技术开发实现的,不过选择一个HTML5开发框架需要考虑哪些方面,首先就是需要什么样的功能,其次就是技术实现,不过当 ...

  2. SAP中常用SM系列事务代码总结

    SM01 锁定事物 SM02 系统信息 SM04 显示在线用户 SM12 删除,显示锁对象 SM13 看update  request SM21 看下系统日志 SM30|SM31 维护table|vi ...

  3. 利用ASCII码生成指定规则的字符串

    /** * 上送终端编号的后两位生成规则 总共可以生成 (36*36-1)1295个编号 * 01...09 0A...0Z * 10...19 1A...1Z * ............... * ...

  4. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

  5. 《Java从入门到放弃》JavaSE入门篇:练习——单身狗租赁系统

    今天,我们要玩个大的!!! 我们把之前使用数组做的这个单身狗系统改版成数据库版本,并且使用面向对象里面的一些简单思想.如果有不知道这个系统的看官,请跳转到目录页,然后再选择单身狗系统(数组版)先围观五 ...

  6. python generator(生成器)

    a=(x*2 for x in range(1000)) # print(a.next())#python2使用 print(a.__next__()) #python3使用 print(next(a ...

  7. React——props的使用以及propTypes

    组件的props是只读的,组件不能修改自己的props,在React中,组件可以接受任意的props,如函数,对象,基本类型以及react元素 一.props的使用 1.一些组件并不需要知道自己的ch ...

  8. All about Div内显示滚动桥

    Div内显示滚动桥看似是一个简单的前端问题,然而实际会发现还是有挺多需要注意的, 本文尝试对div内显示滚动桥的各种主要实现及一些难题进行研究. 横向滚动桥 横向滚动桥比较简单,无需设置宽度,直接ov ...

  9. E2195 cannot evaluate function call

    E2195 cannot evaluate function call :e2195无法评估函数的调用     :问题的根源在于,对组件创建了不合理的触发事件导致的.    :OK

  10. 深入浅出数据结构C语言版(22)——排序决策树与桶式排序

    在(17)中我们对排序算法进行了简单的分析,并得出了两个结论: 1.只进行相邻元素交换的排序算法时间复杂度为O(N2) 2.要想时间复杂度低于O(N2),算法必须进行远距离的元素交换 而今天,我们将对 ...