Java day13

一:线程互斥:多线程同时操作同一个对象
a)很多ATM-----》每台ATM都会同时在进行工作。就相当于多线程。
卡–>主卡,副卡(同一个账号)
//取钱withdraw
//存钱deposit

b)synchronized(共享区){临界区}
共享区:多线程同时操作同一个对象
临界区:多线程对共享区进行操作的代码区
synchronized可以放在方法上,就是一个同步方法。
synchronized可以放在代码上,就是一个同步代码块。

c)并发访问的线程加上同步锁之后就称为线程互斥。
加同步锁,加在共享对象上。
每一个对象都有唯一的一把锁。
lock对象锁---->执行代码------>unlock对象锁

谁抢到了对象锁的线程就先执行。
没有抢到对象锁的线程就等待对象锁。

d) 将所有影响的方法都定义成线程安全的方法就变成了线程安全的类。
线程安全的类—效率低
如Hashtable类

e)什么情况下会释放对象锁:
1)当前线程的同步方法,同步代码块执行结束,
当前线程立即释放对象锁
2)当线程在同步代码块,同步方法中遇到break,
return终止了该代码块,该方法的继续执行,当前
线程将会释放对象锁
3)当线程在同步代码块,同步方法中出现未处理的
Error或Exception,导致了该代码块,该方法异常结束
时将会释放对象锁
4)当线程执行同步代码块,同步方法时,程序执行了
对象锁对象的wait()方法,则当前线程暂停,并释放对象锁。

f)什么情况下,线程不会释放对象锁:
1)线程执行同步代码块或者同步方法时,程序调用Thread.sleep()
方法。Thread.yield方法来暂停当前线程的执行,当前
线程不会释放对象锁。
2)线程执行同步代码块时,其他线程调用了该线程的suspend
方法将该线程挂起,该线程不会释放对象锁,当前,
我们应该尽量避免使用suspend和resume方法来控制线程。

g)同步锁Lock
从jdk1.5之后,Java提供了另外一种线程同步的机制:
它通过显示定义同步锁对象来实现同步,在这种机制下,
同步锁应该使用Lock对象充当。
通常认为:Lock提供了比synchronized方法和synchronized
代码块更广泛的锁定操作,Lock实现允许更灵活的结构,
可以具有差别很大的属性,并且可以支持多个相关的Condition对象,
Lock是控制多个线程对共享资源进行访问的工具。通常,
锁提供了对共享资源的独占访问,每次只能有一个线程对Lock
对象加锁,线程开始访问共享资源之前应先获得Lock对象,不过,
某些锁可能允许对共享资源并发访问。比如ReadWriteLock读写锁。
当前,在实现线程安全的控制中,通过喜欢使用ReentrantLock可重入锁,
使用该Lock对象可以显式加锁,释放锁。
使用Lock对象的代码格式为:
class Test{
private final ReentrantLock lock=new ReentrantLock();
public void test(){
lock.lock();//加锁
try{
//…需要保证线程安全的代码
}finally{
//使用finally块来保证释放锁
lock.unlock();
}
}
}
h)Lock与使用同步方法有点相似,只是使用Lock时显式使用Lock
对象作为同步锁,而使用同步方法时系统隐式使用当前对象作为
对象锁,同样符合“加锁—访问—释放锁"的操作模式,而且
使用Lock对象时每个Lock对象对应一个当前对象,一样可以保证
对于同一个对象,同一时刻只能有一个线程进入临界区。
使用同步方法和同步代码块的机制使得多线程安全编程非常方便。
并且也可以避免很多涉及锁的常见编程错误,但是Lock是更加灵活
的方式,并且Lock还提供了其他的功能。

二:线程的通信—>线程同步(操作的也是同一个对象)
线程互斥谁先抢到对象锁就谁先执行(如抛绣球)。
线程同步会控制线程执行的先后顺序。
线程同步线程会有依赖关系。
一个boy存钱,一个girl取钱。必须先存钱后取钱。就是线程同步。
重复(存钱---->取钱)
存钱之后通知可以取钱。
取钱之后通知可以存钱。
并且是先存后取
男:标志位flag = false;存钱 flag=true;
女:标志位flag = true;取钱 flag=false;
模拟生成者和消费者—针对产品
生成者:从1到100累加的和作为产品。
消费者:打印该产品。
线程通信的步骤:
1)找到共有对象。
2)wait(),notify(),notifyAll()—Object类中的方法。
需要对同一个资源等待,唤醒才有效。
是针对对象进行等待和通知。这些方法一定要放在
synchronized关键字中,用来保护共有资源。
生产者生成产品之后通知消费者–notify
消费者等待生产者生产产品—wait
3)保证wait()执行在notifyAll()方法的前面.使用标志变量。
notifyAll()之前先判断有没有线程在等待。
如果有就通知,没有就小睡一下只有有等待线程出现。

sleep():不会释放对象锁。
wait():让当前线程进入等待状态,会释放对象锁。
notify():通知等待中的某个线程进入到就绪状态。会释放对象锁。
notifyAll():通知等待中的所有线程进入到就绪状态。会释放对象锁。
可以通过公交车和人和师傅来说明

三:线程的死锁
多个线程同时操作多个对象很容易产生死锁。
解决方式:给多个对象加对象锁的时候。
将加锁的顺序保持一致,就可以避免死锁。

四:Thread类中yield()方法
yield():它是一个Thread类提供的一个静态方法,它可以
让当前正在执行的线程暂停,但它不会阻塞该线程,
他只是将该线程转入就绪状态,yield只是让当前线程
暂停一下,让系统的线程调度器重新调度一次,完成
可能的情况是:当某个线程调用了yield方法暂停之后,
线程调度器又将其调度出来重新执行。
实际上,当某个线程调用了yield方法暂停之后,只有
优先级与当前线程相同,或者优先级比当前线程更高
的就绪状态的线程才有获取执行的机会。如果当前没
有比自己优先级还高的线程就没有效果。

关于sleep方法和yield方法的区别如下:
1)sleep方法暂停当前线程后会给其他线程执行机会,
不会理会其他线程的优先级。但yield方法只会给优先级
相同,或优先级更高的线程执行机会。
2)sleep方法会将线程转入阻塞状态,指导经过阻塞时间
才会转入就绪状态,而yield不会将线程转入阻塞状态,
它只是强制当前线程进入就绪状态,因此完全有可能某个
线程调用yield方法暂停之后,立即再次获取处理器资源被执行。
3)sleep方法申明抛出了InterrupedException异常,所以
调用sleep方法是要么捕捉该异常,要么显式申明抛出该异常,
而yield方法泽没有申明抛出任何异常。
4)sleep方法比yield方法有更好的可移植性,通常不要依靠
yield来控制并发线程的执行。

五:改变线程的优先级
每个线程执行时都具有一定的优先级,优先级高的线程获得较多
的执行机会,而优先级低的线程则获得较少的执行机会,每个
线程默认的优先级都与创建他的父线程具有相同的优先级。
在默认情况下,main线程具有普通优先级,由main线程创建的
子线程也有普通优先级。
Thread类提供了setPrioirity和getPriority方法来设置和返回
指定线程的优先级,其中setPrioirty方法的参数是一个整数,
范围是1到10之间,也可以使用Thread类的三个静态常量:
MAX_PRIORITY:其值是10
MIN_PRIORITY:其值是1
NORM_PRIORITY:其值是5
setPrioirity(int)设置线程的优先级.整数越大优先级越高。
注意:虽然Java提供了10个优先级别,但这些优先级别需要操作系统
的支持,不幸的是,不同的操作系统上优先级并不相同,而且也不能
很好地和Java的10个优先级对应,比如windows2000仅提供了7个优先级,
在这种情况,我们应该尽量避免直接为线程指定优先级,而应该使用
线程的三个静态常量来设置优先级,这样才可以保证程序具有最好的
可移植性。

六:后台进程
有一种线程,他是在后台运行的,他的任务是为其他的线程提供服务,
这种线程被称为“后台线程”(Daemon Thread),又称“守护线程”,
或“精灵线程”。JVM的垃圾回收线程就是典型的后台线程。
后台线程有个特征:如果所有的前台线程都死亡,后台线程会自动死亡,
调用Thread对象setDamon(true)方法可将指定线程设置为后台线程,
当整个虚拟机中只剩下后台线程时,程序就没有继续运行的必要了,
所有虚拟机也就退出了。
主线程默认是前台线程,前台线程创建的子线程默认是前台线程,
后台线程创建的子线程默认是后台线程。

### RT-DETRv3 网络结构分析 RT-DETRv3 是一种基于 Transformer 的实时端到端目标检测算法,其核心在于通过引入分层密集正监督方法以及一系列创新性的训练策略,解决了传统 DETR 模型收敛慢和解码器训练不足的问题。以下是 RT-DETRv3 的主要网络结构特点: #### 1. **基于 CNN 的辅助分支** 为了增强编码器的特征表示能力,RT-DETRv3 引入了一个基于卷积神经网络 (CNN) 的辅助分支[^3]。这一分支提供了密集的监督信号,能够与原始解码器协同工作,从而提升整体性能。 ```python class AuxiliaryBranch(nn.Module): def __init__(self, in_channels, out_channels): super(AuxiliaryBranch, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(out_channels) def forward(self, x): return F.relu(self.bn(self.conv(x))) ``` 此部分的设计灵感来源于传统的 CNN 架构,例如 YOLO 系列中的 CSPNet 和 PAN 结构[^2],这些技术被用来优化特征提取效率并减少计算开销。 --- #### 2. **自注意力扰动学习策略** 为解决解码器训练不足的问题,RT-DETRv3 提出了一种名为 *self-att 扰动* 的新学习策略。这种策略通过对多个查询组中阳性样本的标签分配进行多样化处理,有效增加了阳例的数量,进而提高了模型的学习能力和泛化性能。 具体实现方式是在训练过程中动态调整注意力权重分布,确保更多的高质量查询可以与真实标注 (Ground Truth) 进行匹配。 --- #### 3. **共享权重解编码器分支** 除了上述改进外,RT-DETRv3 还引入了一个共享权重的解编码器分支,专门用于提供密集的正向监督信号。这一设计不仅简化了模型架构,还显著降低了参数量和推理时间,使其更适合实时应用需求。 ```python class SharedDecoderEncoder(nn.Module): def __init__(self, d_model, nhead, num_layers): super(SharedDecoderEncoder, self).__init__() decoder_layer = nn.TransformerDecoderLayer(d_model=d_model, nhead=nhead) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=num_layers) def forward(self, tgt, memory): return self.decoder(tgt=tgt, memory=memory) ``` 通过这种方式,RT-DETRv3 实现了高效的目标检测流程,在保持高精度的同时大幅缩短了推理延迟。 --- #### 4. **与其他模型的关系** 值得一提的是,RT-DETRv3 并未完全抛弃经典的 CNN 技术,而是将其与 Transformer 结合起来形成混合架构[^4]。例如,它采用了 YOLO 系列中的 RepNCSP 模块替代冗余的多尺度自注意力层,从而减少了不必要的计算负担。 此外,RT-DETRv3 还借鉴了 DETR 的一对一匹配策略,并在此基础上进行了优化,进一步提升了小目标检测的能力。 --- ### 总结 综上所述,RT-DETRv3 的网络结构主要包括以下几个关键组件:基于 CNN 的辅助分支、自注意力扰动学习策略、共享权重解编码器分支以及混合编码器设计。这些技术创新共同推动了实时目标检测领域的发展,使其在复杂场景下的表现更加出色。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值