java多线程

java多线程
创建线程的第一种方式:继承Thread类
步骤:
1 定义类继承Thread
2 复写Thread类中的run方法
目的:将自定义的代码存储在run方法中,让线程运行。
3 调用线程的start方法,该方法有两个作用,启动线程,调用run方法。

默认名称:Thread-编号 从0开始
static Thread currentThread():获取当前线程对象
getName():获取线程名称

****简单的卖票程序。

第二种方法:创建线程的第二种方式:实现runnable接口
步骤:
1. 定义类实现Runnable接口
2. 覆盖Runnable接口的run方法。
3. 通过Thread类建立线程对象。
4. 将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
5. 调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

两种方式区别:
继承Thread:线程代码存放在Thread子类run方法中
实现Runnable:存在接口的子类的run方法。

synchronized(对象)
{需要被同步的代码}
对象如同锁。持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

同步的前提:
1 必须要有两个或者两个以上线程。
2 必须是多个线程使用同一个锁。

必须保证同步中只能有一个线程在运行。

好处:解决了多线程的安全问题。
弊端:多个线程都需要判断锁,较为消耗资源,

同步函数的锁是this
如果同步函数被静态修饰后,使用的锁是什么呢?
静态的同步方法使用的锁是该方法所在类的字节码文件对象。Ticket.class

单例设计模式:饿汉式,懒汉式(在多线程时)
1.延迟加载 2低效 3锁为字节码文件对象

多线程-死锁:例子:同步中嵌套同步,锁不同

等待唤醒机制。线程池。
wait()
notify()
notifyAll()

为什么这些操作线程的方法要定义Object中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程持有的锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。不可以对不同锁的的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。因此任意对象的方法定义在Object中。

生产者消费者例子:JDK1.5新特性
Lock 替代synchronized  condition await signal signalAll
替代wait notify notifyAll

停止线程的方法:可以调用interrupt,run方法结束

守护线程:t.setDaemon(true) 后台进程,前台结束后自动结束
join()等待线程终止,抢夺CPU执行权
优先级 setPriority(1,5,10)
 yield方法:暂停当前正在执行
线程组概念

-----------------------------------------------------------------------------------------------------
Java API:

具体查文档
String 
StringBuilder:方法调用链
基本数据类型包装类
----------------------------------------------------
集合框架: Collection顶层
为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同。
这个存储方式称之为:数据结构

List:元素是有序的,元素可以重复。因为该集合体系有索引。 

特有方法:带角标的方法。
ArrayList:底层使用的数据结构是数组结构。查询速度很快。但是增删稍慢。线程不同步
1. 添加元素 add 存储的是引用
2. 获取个数 .size();
3. 删除元素 remove  clear清空
4. 判断元素 contains
交集:retainAll
      removeAll
迭代器:iterator
获取迭代器,用于取出集合的元素。
List集合特有的列表迭代器:ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素。只能用迭代器的方法操作元素。

LinkedList:底层使用的是链表数据结构,增删速度快,查询速度慢.add  get和remove的区别。获取时一个不删一个删。  
 1.6后提供  peek   poll 空列表不抛异常返回空
Vector:底层是数组数据结构,线程同步。被ArrayList替代。枚举是Vector特有的取出方式,被迭代器出现。

------------------------------------------------
Set:元素是无序的,元素不可以重复。
HashSet:底层数据结构是哈希表
         保证唯一性:hashCode和equals方法。复写注意格式。线程是非同步的。

TreeSet:可以对Set集合中的元素进行排序。
添加自定义对象:implements Comparable强制让学生具备比较性

。底层数据结构是二叉树,红黑树。保证惟一性:compareTo方法

return 0;
TreeSet排序的第一种方式:让元素具备比较性,称为自然顺序。

comparable 中的compareTo方法。实现Comparable
TreeSet的第二种排序方式。
当元素自身不具备比较性时。或者不是需要的时候。
这时让集合本身具备比较性。定义了比较器,将比较器对象作为参数传递给构造函数。comparator 接口,复写compare方法

**排序时:当主要条件相同时,排序次要条件

泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个安全机制。
ArrayList<String> al = new ArrayList<String>();
好处:
1. 将运行时期出现问题ClassCAstException,转移到编译时期。
2. 避免了强制转换的麻烦。<>用来接收泛型的。
Iterator<String> it=iterator();

泛型类:class Util<T>{}
什么时候定义泛型类,当类中要操作的引用数据类型不确定的时候

。早期定义Object来完成扩展。现在定义泛型来完成扩展。

泛型方法:public <Q> void show(Q q)

泛型定义在接口上

泛型限定:<?> <? extends Person> <? super E>
void printColl(Arraylist<..> al)

-------------------------------------------------
Map集合: 该集合存储键值对。一对一对往里存。而且要保证键值的唯一性。

Map
  |--Hashtable:底层是哈希表数据结构,不可以存入null。该集合是线程同步的。jdk1.0

  |--HashMap:底层是哈希表数据结构,允许使用null值和null键。该集合是线程不同步的。jdk1.2
  |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。和Set很像。Set底层就是使用了Map集合。


HashMap:新的值替换旧的值。

map集合的两种取出方式:
1. keySet:将map中的所有的键存入到Set集合。因为set具备迭代器。根据所有的键get对应的值。

2. entrySet:<Map.Entry<K,V>> 泛型嵌套
//Map.Entry 其实Entry也是一个接口,它是Map接口中的一个内部接口。
map扩展知识:读懂HashMap<String,HashMap<String,String>

工具类:
Collections.
sort(List list)
    .max(Collection c)
           .binarySearch: 有序集合
           .fill  替换
           .replaceAll替换
           .reverse  反转
           .reverseOrder 逆转比较
     SynList:synchronizedList()返回线程安全
     shuffle 随机
Arrays:操作数组
asList()将数组变成list集合**不可以使用集合的增删方法。因为长度固定。

集合变数组:Collection中的方法toArray

1.5新特性:

高级for循环
for(数据类型 变量名:被遍历的集合(Collection)或者数组)**

可变参数:show(int...arr)

import static java.util.Arrays.*; 静态导入。可以不写类名

---------------------------------------------------
其它对象
System:
获取系统属性信息:getProperties()
java -Dhaha=qqqqq SystemDemo

Runtime: 单例设计模式
exec(...)  双斜杠

Date:.util.*;
       java.text.*;
 new Date()当前时间。


Calender:

Math
.Random 0-1的随机数

标题“51单片机通过MPU6050-DMP获取姿态角例程”解析 “51单片机通过MPU6050-DMP获取姿态角例程”是一个基于51系列单片机(一种常见的8位微控制器)的程序示例,用于读取MPU6050传感器的数据,并通过其内置的数字运动处理器(DMP)计算设备的姿态角(如倾斜角度、旋转角度等)。MPU6050是一款集成三轴加速度计和三轴陀螺仪的六自由度传感器,广泛应用于运动控制和姿态检测领域。该例程利用MPU6050的DMP功能,由DMP处理复杂的运动学算法,例如姿态融合,将加速度计和陀螺仪的数据进行整合,从而提供稳定且实时的姿态估计,减轻主控MCU的计算负担。最终,姿态角数据通过LCD1602显示屏以字符形式可视化展示,为用户提供直观的反馈。 从标签“51单片机 6050”可知,该项目主要涉及51单片机和MPU6050传感器这两个关键硬件组件。51单片机基于8051内核,因编程简单、成本低而被广泛应用;MPU6050作为惯性测量单元(IMU),可测量设备的线性和角速度。文件名“51-DMP-NET”可能表示这是一个与51单片机及DMP相关的网络资源或代码库,其中可能包含C语言等适合51单片机的编程语言的源代码、配置文件、用户手册、示例程序,以及可能的调试工具或IDE项目文件。 实现该项目需以下步骤:首先是硬件连接,将51单片机与MPU6050通过I2C接口正确连接,同时将LCD1602连接到51单片机的串行数据线和控制线上;接着是初始化设置,配置51单片机的I/O端口,初始化I2C通信协议,设置MPU6050的工作模式和数据输出速率;然后是DMP配置,启用MPU6050的DMP功能,加载预编译的DMP固件,并设置DMP输出数据的中断;之后是数据读取,通过中断服务程序从DMP接收姿态角数据,数据通常以四元数或欧拉角形式呈现;再接着是数据显示,将姿态角数据转换为可读的度数格
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值