最新文�? 原创 : 嵌入式SD/TF卡通用协议-SDIO协议 原创 : Linux应用编程(五)USB应用开发-libusb库 原创 : Linux内核编程(二十一)USB驱动开发-键盘驱动 原创 : 嵌入式八股文(一)C语言概念 原创 : 嵌入式八股文(二)C语言算法
java 学习笔记 历史版本:
上次修改时间: 2023-08-24 23:08:38
从c++ 入门java 历史版本:
上次修改时间: 2023-06-02 12:00:01
Gradle的基本使用 历史版本:
上次修改时间: 2023-06-02 15:04:35
java多线程 历史版本:
上次修改时间: 2023-06-04 15:15:31
begin\");\n try {\n // 睡眠1年\n Thread.sleep(1000 * 60 * 60 * 24 * 365);\n } catch (InterruptedException e) {\n// e.printStackTrace();\n }\n //1年之后才会执行这里\n System.out.println(Thread.currentThread().getName() + \"---> end\");\n \n }\n}\n```\n\n#### 合理的终止线程\n 做一个boolean类型的标记\n```\n/**\n * @author Mr.乐\n * @Description\n */\npublic class DemoSleep02 {\n public static void main(String[] args) {\n MyRunable4 r = new MyRunable4();\n Thread t = new Thread(r);\n t.setName(\"t\");\n t.start();\n \n // 模拟5秒\n try {\n Thread.sleep(5000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n // 终止线程\n // 你想要什么时候终止t的执行,那么你把标记修改为false,就结束了。\n r.run = false;\n }\n}\nclass MyRunable4 implements Runnable {\n \n // 打一个布尔标记\n boolean run = true;\n \n @Override\n public void run() {\n for (int i = 0; i < 10; i++){\n if(run){\n System.out.println(Thread.currentThread().getName() + \"--->\" + i);\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }else{\n // return就结束了,你在结束之前还有什么没保存的。\n // 在这里可以保存呀。\n //save....\n //终止当前线程\n return;\n }\n }\n }\n}\n```\n##### yield()\n暂停当前正在执行的线程对象,并执行其他线程
\nyield()方法不是阻塞方法。让当前线程让位,让给其它线程使用。
\nyield()方法的执行会让当前线程从“运行状态”回到“就绪状态”。
\n注意:在回到就绪之后,有可能还会再次抢到。
\n\n```\n/**\n * @author Mr.乐\n * @Description 线程让位\n */\npublic class DemoYield {\n public static void main(String[] args) {\n //创建线程\n MyThread5 t01 = new MyThread5(\"线程01\");\n MyThread5 t02 = new MyThread5(\"线程02\");\n MyThread5 t03 = new MyThread5(\"线程03\");\n \n //开启线程\n t01.start();\n t02.start();\n t03.start();\n }\n}\nclass MyThread5 extends Thread{\n public MyThread5() {\n }\n \n public MyThread5(String name) {\n super(name);\n }\n \n @Override\n public void run() {\n for (int i = 0; i < 50; i++) {\n if(30 == i){\n Thread.yield();//当循i环到30时,让线程让步\n //1、回到抢占队列中,又争夺到了执行权\n //2、回到抢占队列中,没有争夺到执行权\n }\n System.out.println(this.getName() + \":\" + i);\n }\n }\n}\n```\n\n\n##### join()\n\n\n\n#### 线程的调度\n线程调度模型\n- 均分式调度模型:所有的线程轮流使用CPU的使用权,平均分配给每一个线程占用CPU的时间。\n- 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么就会随机选择一个线程来执行,优先级高的占用CPU时间相对来说会高一点点。\n\nJava中JVM使用的就是抢占式调度模型\n- getPriority():获取线程优先级\n- setPriority:设置线程优先级\n\n```\n/**\n * @author Mr.乐\n * @Description 线程的调度\n */\npublic class Demo07 {\n public static void main(String[] args) {\n //创建线程\n MyThread t01 = new MyThread(\"线程01\");\n MyThread t02 = new MyThread(\"线程02\");\n MyThread t03 = new MyThread(\"线程03\");\n //获取线程优先级,默认是5\n// System.out.println(t01.getPriority());\n// System.out.println(t02.getPriority());\n// System.out.println(t03.getPriority());\n //设置线程优先级\n t01.setPriority(Thread.MIN_PRIORITY); //低 - 理论上来讲,最后完成\n t02.setPriority(Thread.NORM_PRIORITY); //中\n t03.setPriority(Thread.MAX_PRIORITY); //高 - 理论上来讲,最先完成\n //开启线程\n t01.start();\n t02.start();\n t03.start();\n }\n}\n```\n\n\n#### 线程安全\n线程同步方式
\n同步语句块:synchronized(this){方法体} (synchronized括号后的数据必须是多线程共享的数据,才能达到多线程排队)\n```\n// 以下代码的执行原理?\n// 1、假设t1和t2线程并发,开始执行以下代码的时候,肯定有一个先一个后。\n// 2、假设t1先执行了,遇到了synchronized,这个时候自动找“后面共享对象”的对象锁,\n// 找到之后,并占有这把锁,然后执行同步代码块中的程序,在程序执行过程中一直都是\n// 占有这把锁的。直到同步代码块代码结束,这把锁才会释放。\n// 3、假设t1已经占有这把锁,此时t2也遇到synchronized关键字,也会去占有后面\n// 共享对象的这把锁,结果这把锁被t1占有,t2只能在同步代码块外面等待t1的结束,\n// 直到t1把同步代码块执行结束了,t1会归还这把锁,此时t2终于等到这把锁,然后\n// t2占有这把锁之后,进入同步代码块执行程序。\n//\n// 这样就达到了线程排队执行。\n// 这里需要注意的是:这个共享对象一定要选好了。这个共享对象一定是你需要排队\n// 执行的这些线程对象所共享的。\n synchronized (this){\n double before = this.getBalance();\n double after = before - money;\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n this.setBalance(after);\n }\n```\n普通同步方法:\n```\n修饰符 synchronized 返回值类型 方法名(形参列表){方法体}\n```\nsynchronized出现在实例方法上,一定锁的是this(此方法)。不能是其他的对象了。 所以这种方式不灵活。
\n另外还有一个缺点:synchronized出现在实例方法上, 表示整个方法体都需要同步,可能会无故扩大同步的 范围,导致程序的执行效率降低。所以这种方式不常用。\n
\n\n```\n public synchronized void withdraw(double money){\n double before = this.getBalance(); // 10000\n // 取款之后的余额\n double after = before - money;\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n \n // 更新余额\n this.setBalance(after);\n```\n静态同步方法:修饰符 synchronized static 返回值类型 方法名(形参列表){方法体}\n(静态方法中不能使用this)表示找类锁。类锁永远只有1把。\n\n\n##### Lock\n应用场景不同,不一定要在同一个方法中进行解锁,如果在当前的方法体内部没有满足解锁需求时,可以将lock引用传递到下一个方法中,当满足解锁需求时进行解锁操作,方法比较灵活。\n
\n\n```\n private Lock lock = new ReentrantLock();//定义Lock类型的锁\n public void withdraw(double money){\n // t1和t2并发这个方法。。。。(t1和t2是两个栈。两个栈操作堆中同一个对象。)\n // 取款之前的余额\n lock.lock();//上锁\n double before = this.getBalance(); // 10000\n // 取款之后的余额\n double after = before - money;\n // 在这里模拟一下网络延迟,100%会出现问题\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n \n // 更新余额\n // 思考:t1执行到这里了,但还没有来得及执行这行代码,t2线程进来withdraw方法了。此时一定出问题。\n this.setBalance(after);\n lock.unlock();//解锁\n }\n```\n\n###### 死锁\n形成原因
\n当两个线程或者多个线程互相锁定的情况就叫死锁
\n避免死锁的原则
\n顺序上锁,反向解锁,不要回头
\n\n```\n/**\n * @author Mr.乐\n * @Description 死锁\n */\npublic class DeadLock {\n public static void main(String[] args) {\n Object o1 = new Object();\n Object o2 = new Object();\n \n // t1和t2两个线程共享o1,o2\n Thread t1 = new MyThread1(o1,o2);\n Thread t2 = new MyThread2(o1,o2);\n \n t1.start();\n t2.start();\n }\n}\n \nclass MyThread1 extends Thread{\n Object o1;\n Object o2;\n public MyThread1(Object o1,Object o2){\n this.o1 = o1;\n this.o2 = o2;\n }\n public void run(){\n synchronized (o1){\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n synchronized (o2){\n \n }\n }\n }\n}\n \nclass MyThread2 extends Thread {\n Object o1;\n Object o2;\n public MyThread2(Object o1,Object o2){\n this.o1 = o1;\n this.o2 = o2;\n }\n public void run(){\n synchronized (o2){\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n synchronized (o1){\n \n }\n }\n }\n}\n```\n\n\n#### 守护线程\njava语言中线程分为两大类:\n1. 用户线程\n2. 守护线程(后台线程)\n其中具有代表性的就是:垃圾回收线程(守护线程)。\n\n守护线程的特点:\n- 一般守护线程是一个死循环,所有的用户线程只要结束,\n- 守护线程自动结束。\n \n\n注意:主线程main方法是一个用户线程。
\n守护线程用在什么地方呢?
\n每天00:00的时候系统数据自动备份。
\n这个需要使用到定时器,并且我们可以将定时器设置为守护线程。
\n一直在那里看着,每到00:00的时候就备份一次。所有的用户线程
\n如果结束了,守护线程自动退出,没有必要进行数据备份了。
\n\n\n```\npublic class Demo09 {\n public static void main(String[] args) {\n Thread t = new BakDataThread();\n t.setName(\"备份数据的线程\");\n \n // 启动线程之前,将线程设置为守护线程\n t.setDaemon(true);\n t.start();\n // 主线程:主线程是用户线程\n for(int i = 0; i < 10; i++){\n System.out.println(Thread.currentThread().getName() + \"--->\" + i);\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }\n }\n}\n \nclass BakDataThread extends Thread {\n public void run(){\n int i = 0;\n // 即使是死循环,但由于该线程是守护者,当用户线程结束,守护线程自动终止。\n while(true){\n System.out.println(Thread.currentThread().getName() + \"--->\" + (++i));\n try {\n Thread.sleep(1000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }\n }\n}\n```\n\n#### wait和notify方法\nwait和notify方法不是线程对象的方法,是java中任何一个java对象都有的方法,因为这两个方式是Object类中自带的。
\n\n1. 必须配合synchronized使用\n2. 且使用的必须为同一个对象:synchronized (A)配合A.wait()使用\n3. 当线程执行到object.wait()时,此线程会同时释放锁synchronized (object);当它结束了wait后,此线程又会重新去争抢锁synchronized (object)。\n\n```\npublic class Wait {\n public static void main(String[] args) throws InterruptedException {\n Object object=new Object();\n Thread thread=new Thread(()->{\n synchronized (object){\n try {\n object.wait();\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n System.out.println(\"执行完成\");\n }\n });\n thread.start();\n }\n}\n\n```\n\n执行结果:\n当前程序中不存在满足wait结束等待的条件,所以永远不会输出执行完成
\n\n\nwait结束等待:
\n\n必须使用notify:
\n必须配合synchronized使用;
\n且在notify后,当前线程不会马上释放锁,要等到当前线程被synchronized修饰的代码执行完,才会释放锁;
\n使用notify的对象为A,则只能唤醒A.wait()的线程,不能唤醒B.wait()的线程;
\n****小区别:
\nnotify()方法——随机唤醒一个wait的线程
\nnotifyAll()方法——唤醒所有wait的线程,让这些被唤醒的线程去争抢,按争抢顺序依次执行
\n\n```\npublic class Wait_notify2 {\n public static void main(String[] args) {\n\n Object object=new Object();\n Thread thread1=new Thread(()->{\n synchronized (object){\n try {\n object.wait();\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }\n System.out.println(\"线程1执行完成\");\n });\n\n Thread thread2=new Thread(()->{\n synchronized (object){\n try {\n object.wait();\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }\n System.out.println(\"线程2执行完成\");\n });\n\n Thread thread3=new Thread(()->{\n synchronized (object){\n try {\n object.wait();\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }\n System.out.println(\"线程3执行完成\");\n });\n thread1.start();\n thread2.start();\n thread3.start();\n\n Thread thread4=new Thread(()->{\n synchronized (object){\n //使用一次notify只能唤醒一个线程;\n //使用一次notifyAll可唤醒所有的线程\n object.notify(); \n object.notifyAll();\n System.out.println(\"线程4去唤醒wait的线程\");\n }\n\n });\n thread4.start();\n\n\n }\n}\n\n```\n\n![image.png](https://www.testingcloud.club/sapi/api/image_download/2dd304b3-02a7-11ee-9dd3-525400986ccb.png)\n\n打断一个wait()操作
\n.使用interrupted
\n调用该等待线程的interrupted方法,但会抛出异常;然后继续执行wait后的代码
\n```\npublic class Wait_interrupted {\n public static void main(String[] args) throws InterruptedException {\n Object object=new Object();\n Thread thread1=new Thread(()->{\n System.out.println(\"线程1去获得锁\");\n synchronized (object){\n System.out.println(\"线程1得到了锁\");\n try {\n object.wait();\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }\n System.out.println(\"线程1执行完成\");\n\n });\n thread1.start();\n\n //让主线程休眠一会,让线程1去得到锁并且处于休眠wait\n Thread.sleep(500);\n\n System.out.println(\"使用线程2去打断线程1的wait\");\n //打断线程1\n thread1.interrupt();\n }\n}\n```\n\n![image.png](https://www.testingcloud.club/sapi/api/image_download/6464becb-02a7-11ee-9dd3-525400986ccb.png)\n\n
\nwait时间超时\n当时间超时,会自动恢复执行,会重新去获得锁,然后从wait的下一行开始执行
\n```\npublic class Wait_timeout {\n public static void main(String[] args) {\n Object object=new Object();\n Thread thread1=new Thread(()->{\n System.out.println(\"去获得锁\");\n synchronized (object){\n System.out.println(\"得到了锁\");\n try {\n object.wait(10000);\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n }\n System.out.println(\"线程1执行完成\");\n\n });\n thread1.start();\n }\n}\n\n```\n -->
android开发笔记 历史版本:
上次修改时间:
java ee 历史版本:
上次修改时间:
���������ٶ�?? 历史版本:
上次修改时间:
类和接口 历史版本:
上次修改时间:
使用注解简化类定成员变量定义LomBook 历史版本:
上次修改时间: 2024-07-06 01:26:14
0条评�?
全部评论

关于博主

an actually real engineer

通信工程专业毕业,7年开发经验

技术栈:

精通c/c++

精通golang

熟悉常见的脚本,js,lua,python,php

熟悉电路基础,嵌入式,单片机

耕耘领域:

服务端开发

嵌入式开发

git

>

gin接口代码CURD生成工具

sql ddl to struct and markdown,将sql表自动化生成代码内对应的结构体和markdown表格格式,节省宝贵的时间。

输入ddl:
输出代码:

qt .ui文件转css文件

duilib xml 自动生成绑定控件代码

协议调试器

基于lua虚拟机的的协议调试器软件 支持的协议有:

串口

tcp客户端/服务端

udp 组播/udp节点

tcp websocket 客户端/服务端

软件界面

使用例子: 通过脚本来获得接收到的数据并写入文件和展示在界面上

下载地址和源码

duilib版本源码 qt qml版本源码 二进制包

webrtc easy demo

webrtc c++ native 库 demo 实现功能:

基于QT

webrtc摄像头/桌面捕获功能

opengl渲染/多播放窗格管理

janus meeting room

下载地址和源码

源码 二进制包

wifi,蓝牙 - 无线开关

实现功能:

通过wifi/蓝牙实现远程开关电器或者其他电子设备

电路原理图:

实物图:

深度学习验证工具

vtk+pcl 点云编辑工具

实现功能:

1. 点云文件加载显示(.pcd obj stl)

2. 点云重建

3. 点云三角化

4. 点云缩放

下载地址:

源码 二进制包

虚拟示波器

硬件实物图:

实现原理

基本性能

采集频率: 取决于外部adc模块和ebaz4205矿板的以太网接口速率,最高可以达到100M/8 约为12.5MPS

上位机实现功能: 采集,显示波形,存储wave文件。

参数可运行时配置

上位机:

显示缓冲区大小可调

刷新率可调节

触发显示刷新可调节

进程守护工具

基本功能:

1. 守护进程,被守护程序崩溃后自动重启。

2. 进程输出获取,显示在编辑框中。

二进制包

openblt 烧录工具

基本功能:

1. 加载openblt 文件,下载到具有openblt bootloader 运行的单片机中。

二进制包

opencv 功能验证工具(开源项目二次开发)

基本功能:

1. 插件化图像处理流程,支持自定义图像处理流程。 2. 完善的日志和权限管理

二进制包

又一个modbus调试工具

最近混迹物联网企业,发现目前缺少一个简易可用的modbus调试工具,本软件旨在为开发者提供一个简单modbus测试工具。
主打一个代码简单易修改。
特点:

1. 基于QT5

2. 基于libmodbus

3. 三方库完全跨平台,linux/windows。

二进制包

屏幕录制工具

1. 基于QT5

2. 基于ffmpeg

3. 支持自定义录屏

源代码

开源plutosdr 板卡

1. 完全开源

2. 提高固件定制服务

3. 硬件售价450 手焊产量有线

测试数据

内部DDS回环测试

接收测试

外部发送500MHZ FM波形

硬件原理图

matlab测试

2TRX版本

大部分plutosdr应用场景都是讲plutosdr板卡作为射频收发器来使用。
实际上plutosdr板卡本身运行linux 操作系统。是具有一定脱机运算的能力。 对于一些微型频谱检测,简单射频信号收发等应用完全可以将应用层直接实现在板卡上
相较于通过网卡或者USB口传输具有更稳定,带宽更高等优点。
本开源板卡由于了SD卡启动,较原版pluto支持了自定义启动应用的功能。
提供了应用层开发SDK(编译器,buildroot文件系统)。
通过usb连接电脑,经过RNDIS驱动可以近似为通过网卡连接
(支持固件的开发定制)。

二次开发例子

``` all:
arm-linux-gnueabihf-gcc -mfloat-abi=hard --sysroot=/root/v0.32_2trx/buildroot/output/staging -std=gnu99 -g -o pluto_stream ad9361-iiostream.c -lpthread -liio -lm -Wall -Wextra -lrt
clean:
rm pluto_stream

bsdiff算法补丁生成器

1. 官方bsdiff算法例子自带bzip压缩方式

2. 本例子没有压缩,直接生成补丁文件

3. 图形化界面基于DUILIB

二进制文件

版面分析即分析出图片内的具体文件元素,如文档标题,文档内容,文档页码等,本工具基于cnstd模型

Base64 Image

. 闽ICP备19002644号