学习线程的主要知识点概要如下:

进程和线程的区别:

 *     1.进程:操作系统而言,进程就是程序,多进程就是多个程序同时执行
 *         一个进程包含一个~多个线程,每一个进程都有自己的代码和运行空间,进程之间切换开销较大,进程是资源分配的最小单位
 *     2.线程:程序中的顺序流,多线程:一个程序中的多个顺序流同时执行
 *         一系列线程共享代码和数据空间,每个线程都有自己的程序计数器,
线程之间切换开销较小,线程是cpu调度的最小单位

线程和进程的状态:  新生  就绪   运行  阻塞   终止  

CPU只会给就绪状态和运行状态的线程时间片,不会给阻塞状态的

新生状态:线程创建完就是新生状态

就绪状态:当调用start()方法就是进入就绪状态,等待CPU给时间片,不给时间片不执行,时间片用完了也进入就绪状态

运行状态:当CPU给之间片真正执行的时间,当时间片用完了,继续回到就绪状态

阻塞状态:在阻塞状态时,CPU必定不会给时间片,因为被阻塞了,必须等待其进入到就绪状态才行

终止状态:线程被终止了

如何进入到就绪状态
 *     1.start()
 *     2.阻塞解除
 *     3.线程切换,被切换的线程进入到就绪状态
 *     4.yield()    礼让线程

如何进入到阻塞状态

1.sleep(毫秒数) 方法       当时间结束了就自动回到就绪状态

2.join()方法                     当被插队的结束了才能回到就绪状态

3.wait()方法                   一直等待,直到被notify()方法唤醒才能进入到就绪状态

thread.join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程t的join()方法,直到线程t执行完毕后,才会继续执行线程B。

  • t.join();      //在B线程中使调用线程 t 在此之前执行完毕。
  • t.join(1000);  //在B线程中,等待 t 线程,等待时间是1000毫秒

注意:如果线程被生成了,但还未被起动,调用它的 join() 方法是没有作用的,将直接继续向下执行

如何让一个线程进入到终止状态
1.正常执行完毕

2.destroy() |stop()      已过时

3.通过标识手动判断

sleep() 线程休眠
 *     1.模拟网络延迟
 *     2.放大问题的可能性
 *     抱着资源睡觉,同步的对象资源,让出cpu的资源

yield() 有这个方法的线程是高风亮节,礼让线程

当A,B线程同时开启时候,当A中有yield()方法,在执行A中的方法时候,遇到yield方法,这个线程就回到就绪状态,再次调用的时候就会接着上次没有执行的代码向下执行!!!!!!!!!!!!!!!!!!

如何创建一个线程

 *     1) 继承Thread,重写run()方法
 *         1)在run()方法中定义线程体
 *         2)开启: 使用start()方法开启线程
 *     2) 实现Runnable接口,重写run()方法  推荐
 *     3) 实现Callable接口,重写call()方法

第一种:单继承Thread类,重写run方法:

public class ThreadDemo01 extends Thread{//多线程的线程体@Overridepublic void run() {for(int i=1;i<=20;i++){System.out.println("一遍吃饭...");}}public static void main(String[] args) {//开启多线程 创建线程ThreadDemo01 th=new ThreadDemo01();th.start();           //开启线程//th.run();   注意:这是方法的调用,不是多线程的开启for(int i=1;i<=20;i++){System.out.println("一遍说话...");}//th.start();   放在这里的话:主线程中代码执行完毕,只剩下一个th线程,看不到线程切换的效果}
}

第二种,实现runnable接口,避免单继承的局限性,推荐使用

public class ThreadDemo02 implements Runnable{//定义线程体的方法,当被调用的时候,会逐行执行里面的代码@Overridepublic void run() {for(int i=1;i<=10;i++){System.out.println("一遍敲代码...");}}public static void main(String[] args) {ThreadDemo02 th=new ThreadDemo02();//创建线程//开启线程Thread t=new Thread(th);  //因为开启线程的方法在Thread类中,Thread做为代理类出现,静态代理t.start();for(int i=1;i<=10;i++){System.out.println("一遍陪女朋友...");}}
}

练习:

 * 模拟12306 
 *     需求: 100张票,3个人买完
 *     资源共享: 100张票

下面的代码会造成多人抢到一张票的问题,待优化

在创建线程的时候Thread th1=new Thread(web,"王冬冬");th1作为代理出现,web指的是代理哪一个线程,第二个指的是线程名

public class Web12306_03 implements Runnable{//成员 资源int tikets=100;@Overridepublic void run() {//循环买票while(true){if(tikets<=0){break;}try {Thread.sleep(1);  //线程睡眠100ms} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"正在购买第"+tikets--);}}public static void main(String[] args) {Web12306_03 web=new Web12306_03();//开启三个线程Thread th1=new Thread(web,"王冬冬");Thread th2=new Thread(web,"王宇晨");Thread th3=new Thread(web,"郭友波");th1.start();th2.start();th3.start();}
}

线程的优先级

* 线程的优先级: 提高优先执行的可能性,但是不一定就会先执行
 *     void setPriority(int newPriority) 更改线程的优先级。 
 *     1~10 1最小  10最大
 *     Thread.NORM_PRIORITY 5
 *     Thread.MAX_PRIORITY  10
 *     Thread.MIN_PRIORITY  1

可以直接输入数字                th.getPriority()    //5/10/1/...         th.getState()//获得状态      new  /   runnable    time_waiting


synchronized  同步锁

锁方法简单,但是效率低,因为锁的是整个,要效率可以锁代码块

* 线程安全:
 *     多个线程同时操作同一个资源的时候,才可能会出现线程安全问题,例如上述的抢票
 * 
 * 通过同步synchronized关键字控制线程安全:
 *     同步方法 
 *         静态方法
 *         成员方法
 *     同步块 synchronized(类的class对象|this|资源){代码}      锁住的必须是不可变的
 *         类: 类名.class 一个类的Class对象 一个类只有一个Class对象   this和static不能同时使用      
 * 
 *  锁要锁着不变的东西,会变的锁不住,锁住资源
 *  同步的范围 {} 中的内容太大,效率低,同步的范围太小,锁不住
 *  单例模式:懒汉式

public static synchronized Single newInstance(){System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");if(single==null){single=new Single();}return single;}
public static Single newInstance(){System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");System.out.println("啦啦啦啦啦啦啦啦啦啦啦啦");synchronized (Single.class) {  //控制多线程排队执行if(single==null){System.out.println("-----------------------");single=new Single();}}  //{}中的代码就是排队执行的代码return single;}

synchronized 可以锁类,可以锁this,可以锁资源

当锁类的时候,相当于把这个类的所有对象整个锁住了

同步this,同步当前对象,锁住这个对象,这个对象的所有资源都被锁住了

如果只想要锁住其中某个资源,可以只锁这个资源,一般是成员变量

线程通信

 *     wait() 和 notify()通过操作同一份资源控制线程的通信,方法必须使用在同步的环境下
 *     wait()进入到对象(资源)的等待池中排队等待,等待被唤醒,会让出cpu的资源,同时也会释放对象的锁
 *         sleep() 让出cpu的资源,不会释放对象的锁
 *     notify() 唤醒正在等待的线程,只是具备了可执行的能力,就绪状态,如果想要执行,除了获取cpu的资源以外,还要拿到对象的锁

public class Demo01 extends Object{public static void main(String[] args) {Street street=new Street();new Thread(new Person(street)).start();new Thread(new Car(street)).start();}
}
class Street{//信号灯boolean flag=false;//we 东西 falsepublic void we(){if(flag==true){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}else{try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("车走...");flag=true;this.notify();}}//ns 南北 truepublic void ns(){if(flag==false){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}else{try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("人走...");flag=false;this.notify();}}
}
//人
class Person implements Runnable{Street street=null;  //街道public Person(Street street) {super();this.street = street;}@Overridepublic  void run() {synchronized (street) {while(true){street.ns();}}}
}
class Car implements Runnable{Street street=null; //街道public Car(Street street) {super();this.street = street;}@Overridepublic synchronized void run() {synchronized (street) {while(true){street.we();}}}
}

java重点基础:线程和同步锁和线程通信相关推荐

  1. 【JAVA SE】第十六章 进程、线程、同步锁和线程锁的简介

    第十六章 进程.线程.同步锁和线程安全问题 文章目录 第十六章 进程.线程.同步锁和线程安全问题 一.进程 1.基本介绍 2.进程模型 二.线程 1.基本介绍 2.线程的生命周期 3.线程的优先级 4 ...

  2. 同步锁 php,python线程中同步锁详解

    这篇文章主要为大家详细介绍了python线程中同步锁的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十 ...

  3. java 同步锁_java线程中的同步锁和互斥锁有什么区别?

    在java中,同步锁和互斥锁英文关键字都是Synchronized,没有本质上的区别,两者都包括对资源的独占,使用起来没有区别.概念上的区别是 1:互斥是通过竞争对资源的独占使用,彼此没有什么关系,执 ...

  4. 线程及同步的性能 – 线程池/ ThreadPoolExecutors/ ForkJoinPool

    线程池和ThreadPoolExecutors 虽然在程序中可以直接使用Thread类型来进行线程操作,但是更多的情况是使用线程池,尤其是在Java EE应用服务器中,一般会使用若干个线程池来处理来自 ...

  5. Python 多线程、守护进程、同时运行最大线程数、锁、线程阻塞(线程暂停和继续)

    python 多线程的使用笔记 1.多线程的基本用法 (1)简单任务多线程的开启方式 from threading import Thread import timedef target(name, ...

  6. Java并发基础:了解无锁CAS就从源码分析

    CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...

  7. Java并发基础:了解无锁CAS就从源码分析 1

    CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...

  8. java 同步解决不安全类_「JAVA」Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好...

    线程不安全 线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来:示例代码如下: public class ImplementsDemo { public static void ...

  9. JAVA 基础(第二十六天)同步锁

    目录 1 同步锁 1.1 前言 1.2 同步与异步 1.3 synchronized同步关键字 1.3.1 写法 1.3.2 前提 1.3.3 特点 1.4.1练习-改造售票案例 1.4.2 练习-改 ...

最新文章

  1. 【组合数学】递推方程 ( 递推方程示例 2 汉诺塔 | 递推方程示例 3 插入排序 )
  2. 服务器保存excel文件慢,从使用IE的服务器缓慢地保存Excel文件
  3. 适配器模式(为被封装对象提供不同的接口)
  4. mysql主从克隆服务器_mysql主从复制服务器配置
  5. java中非法运算符_Java 中的运算符和流程控制相关内容的理解
  6. SpringBoot2.0 整合 RocketMQ ,实现请求异步处理
  7. 修改数据_如何批量修改数据库中的特定记录数据
  8. 打开网页到我们看到页面显示的过程中发生了什么?
  9. 使用ajax请求cgi,Python CGI同步AJAX请求
  10. 欧姆龙NX系列PLC和工业软件的搜集资料
  11. PID算法 旋转倒立摆与平衡车的区别。此贴会更新。
  12. 通过 PPT 快速给证件照换底色
  13. 腾讯裁员范围扩大;研究称人类或能喝到月球冰火水;苹果考虑取消京东方3000万块屏幕订单;近视手术无法治愈近视
  14. NLP之分词技术理论
  15. Python爬虫获取网易云歌单封面(带Cookie)
  16. 用Python的statsmodels包做前向逐步回归
  17. TED-4-美好人生的定义
  18. Java 8 Update 201 (8u201)
  19. 基于微信小程序的面包店在线服务系统
  20. Ubuntu零基础教学-GParted磁盘分区工具使用|超级详细,手把手教学

热门文章

  1. bundle install 命令
  2. 集群服务器定时任务重复执行的解决方案
  3. 美国科技大亨换儿子血浆实现“永葆青春”?
  4. 使用雅虎邮箱的几大收获
  5. WCH RISC-V系列芯片使用cJson注意事项
  6. 创业板酝酿多项改革,未盈利互联网企业上市有望破题
  7. Android设备设置代理的两种方法
  8. General(HTTP)
  9. python读取txt文件写入-python txt文件的写入和读取
  10. 程序员自学理财2~理财必读《富爸爸穷爸爸》备忘录