java线程

概述
  • 进程:运行时概念,运行的应用程序,进程间不能共享内存
  • 线程:应用程序内并发执行的代码段,可以共享堆内存和方法区内存,而栈内存是独立的。
  • 并发理解:在单核机器上,从微观角度来看,一段时间内cup只能执行一个任务,但是因为cup在只执行一段代码段的时候大部分的时间是处于等待程序的,所以可以再开几条程序,然后通过轮询机制,让cpu执行多个进程,从宏观角度来看就是所谓的并发。如果机器是多核,那么就是真正的并发。
线程调度模型
  • 线程的调度模型分为: 分时调度模型和抢占式调度模型,Java使用抢占式调度模型

    • 分时调度模型: 所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
    • 抢占式调度模型: 优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些.
  • 线 程 优 先 级 主 要 分 三 种 : MAX_PRIORITY( 最 高 级 );MIN_PRIORITY ( 最 低 级 )NORM_PRIORITY(标准)默认
java 程序的运行原理?
  • java 命令会启动 java 虚拟机,启动 JVM,等于启动了一个应用程序,表示启动了一个进程。该进程会自动启动一个“主线程”,然后主线程去调用某个类的 main 方法。所以 main方法运行在主线程中。在此之前的所有程序都是单线程的。
  • 一个栈就是一个线程,所谓的并发就是多个不同的栈。
线程创建
  • 继承Thread

    • 线程编写要继承 java.lang.Thread
    • 重写run方法
    • 调用的时候调用线程类的start()方法,run方法是让cpu调用的。所以start()方法调用后run方法不会立刻调用。
  • 实现runable接口
class CreateRunnable implements Runnable {
@Override
publicvoid run() {
for (inti = 0; i< 10; i++) {
System.out.println("i:" + i);
}
} }
public class ThreadDemo2 {
publicstaticvoid main(String[] args) {
System.out.println("-----多线程创建开始-----");
// 1.创建一个线程
CreateRunnable createThread = new CreateRunnable();
// 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法
System.out.println("-----多线程创建启动-----");
Thread thread = new Thread(createThread);
thread.start(); }
}
  • 使用匿名内部调用
System.out.println("-----多线程创建开始-----");
Thread thread = new Thread(new Runnable() {
public void run() {
for (int i = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
});
thread.start();
System.out.println("-----多线程创建结束-----");
线程分类
  • 主线程、子线程、GC线程

    • 一个进程中肯定要有主线程。一般是用main函数来创建
    • java主线程结束是不影响子线程的。
    • GC线程是守护线程。
    • 守护线程随着主线程的销毁而销毁。
    • 在一个线程start前用thread.setDaemon(true)可以将用户线程变成守护线程。
  • 守护线程和用户线程
    • 从线程分类上可以分为:用户线程(以上讲的都是用户线程),另一个是守护线程。
    • 其它所有的用户线程结束,则守护线程退出!因为 daemon守护线程是守护非守护线程的
    • setDaemon(true) 使线程变成守护线程
    • 守护线程一般都是无限执行的.
    • 例如 java 中著名的垃圾回收器GC线程就是一个守护线程。
线程安全和锁
  • 任何对象都可以是锁,因为锁的本质是参照物,类似于红绿灯,上课铃等等,关键是大家要看一个参照物。
  • 同步代码块(以object为锁)
		synchronized(object){
[并发逻辑]
}
  • 加锁里的逻辑要尽量少
  • 同步方法
	public synchronized int getTicket(){

	}
  • 同步方法(非静态)是以当前对象作为锁。

    • 如果用非静态同步方法加锁,一般独立出一个对象池,将同步方法放在对象池内,然后多线程对象每次从同一个对象池取资源。
  • 同步方法(静态) 是以类作为锁。
线程生命周期



  • yield();方法可以让线程方法暂时放弃cpu的抢占,但是一旦放弃后又马上开始抢,有谦让的意义
  • Thread.sleep(time) 静态方法 让当前线程休眠time毫秒,不去抢占cpu
  • join等到指定的线程执行完后执行
sleep() 与 wait()的比较
  • 相同点:wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”
  • 不同点:wait()会释放对象的同步锁,而sleep()则不会释放锁
join()方法作用
  • 当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1
线程死亡
  • 有两个原因会导致线程死亡:

    - 1) run方法正常退出而自然死亡,

    - 2) 一个未捕获的异常终止了run方法而使线程猝死。

    - 为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false.
阻塞状态
  • 线程运行过程中,可能由于各种原因进入阻塞状态:

    • 1>线程通过调用sleep方法进入睡眠状态;
    • 2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
    • 3>线程试图得到一个锁,而该锁正被其他线程持有;
    • 4>线程在等待某个触发条件;
参考

最新文章

  1. php实现设计模式之代理模式
  2. Spring MVC学习笔记——返回JSON对象
  3. c# UrlEncode,UrlDecode
  4. iOS图片编辑功能实现
  5. 数据库知识整理&lt;三&gt;
  6. c point ccccc
  7. Call to undefined function imagettftext()解决方法
  8. ♫【模式】Curry化
  9. display 属性
  10. 用彩虹表破解MD5、LM Hash等复杂加密密码
  11. hdu 1298 T9(特里+DFS)
  12. Java 8 Learn Notes - Streams
  13. Java IO流之【缓冲流和文件流复制文件对比】
  14. ASP.NET Core MVC 控制器创建与依赖注入
  15. Elasticsearch 的分页报错 result window is too large
  16. golang从简单的即时聊天来看架构演变
  17. 家庭记账本小程序之框架设计(java web基础版一)
  18. Delphi TXLSReadWriteII导出Excel
  19. Python3 tkinter基础 Canvas create_rectangle 画矩形
  20. ORACLE默认实例设置--linux

热门文章

  1. 24.configparser&amp;hashlib
  2. jquery简单实现复选框的全选与反选
  3. Redis 都有哪些数据类型?分别在哪些场景下使用比较合适?
  4. ansible批量部署tomcat
  5. Spring的一些基本概念(面试备用哦)
  6. bootstrap4.4 Stretched link的使用
  7. 17.python自定义模块的导入方式
  8. OAuth2.0概念以及实现思路简介
  9. P1828 香甜的黄油 Sweet Butter 最短路 寻找一个点使得所有点到它的距离之和最小
  10. 初探ASP.NET Core 3.x (1) - 关于ASP.NET Core