JUC源码学习笔记1——AQS和ReentrantLock

🚀 优质资源分享 🚀

学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统
笔记主要参考《Java并发编程的艺术》并且基于JDK1.8的源码进行的刨析,此篇只分析独占模式,后续在ReentrantReadWriteLock和 CountDownLatch中 会重点分析AQS的共享模式

一丶Lock

锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁可以防止多个线程同时访问共享资源(这种锁称为独占锁,排他锁)但是有些锁可以允许多个线程并发访问共享资源,比如读写锁

1.Lock接口的方法:

方法作用
void lock()获取锁,调用该方法的线程将会获取锁,当锁获得之后从该方法返回
void lockInterruptibly()可中断地获取锁,该方法会响应中断,在锁的获取可以中断当前线程,如果在获取锁之前设置了中断标志,or获取锁的中途被中断or其他线程中断该线程则抛出InterruptedException并清除当前线程的中断状
boolean tryLock()尝试非阻塞的获取锁,调用方法会立即返回,如果可以获取到锁返回true
boolean tryLock(long time, TimeUnit unit) throws InterruptedException超时获取锁,从当前返回有三种情况1.超时时间内获取到锁2.当前线程在超时时间内被中断3.超时间结束没有获取到锁,返回false
void unLock释放锁
Condition newCondition()获取等待通知的组件,该组件和当前锁绑定,只有获取到锁调用wait方法后当前线程将放弃锁,后续被其他线程signal继续争抢锁

2.Lock相比synchronized具备的特性

  • 尝试非阻塞的获取锁
  • 响应中断的获取锁
  • 超时获取锁
synchronized相比于Lock 更加简单,更不容易犯错,但是不够灵活

3.使用Lock的经典范式

获取锁的过程不要写在try中,避免获取锁失败最后finally释放其他线程持有的锁

二丶AbstractQueuedSynchronizer队列同步器

使用一个int成员变量state表示同步状态,内置的FIFO队列来完成资源的获取和线程的排队工作,支持独占也支持共享的获取同步状态。

三个变量被volatile修饰,保证其线程可见性

1.队列同步器可以被重写的方法

方法说明
protected boolean tryAcquire(int arg)独占的获取锁,需要查询当前状态并判断同步状态是否符合预期,然后再进行CAS改变同步状态
protected boolean tryRelease(int arg)独占式释放同步状态,等待获取同步状态的线程将有机会获取同步状态
protected int tryAcquireShared(int arg)共享式的获取同步状态,放回大于等于0()的值表示成功,反之失败
protected boolean tryReleaseShared(int arg)共享式释放同步状态
protected boolean isHeldExclusively()当前队列同步器释放再独占模式下被线程占用,一般表示当前线程是否独占

2.队列同步器提供的模板方法

方法说明
void acquire(int arg)独占式获取同步状态,如果获取成功那么直接返回,反之进入同步队列中等待,
void acquireInterruptibly(int arg)和acquire,但是此方法支持在获取锁的过程中响应中断,如果当前线程被中断那么抛出InterruptedException
boolean tryAcquireNanos(int arg, long nanosTimeout)在acquireInterruptibly的基础上增加了超时限制,如果在指定时间内没有获取到同步状态那么返回false反之true
void acquireShared(int arg)共享式获取同步状态,如果没有获取到那么进入等待队列等待,和acquire不同的式支持同一个时刻多个线程获取同步状态
void acquireSharedInterruptibly(int arg)和acquireShared类似但是支持响应中断
boolean tryAcquireSharedNanos(int arg, long nanosTimeout)在acquireSharedInterruptibly新增了超时限制
boolean release(int arg)独占式释放同步资源,在释放同步状态后唤醒后继线程
boolean releaseShared(int arg)共享式释放同步状态
CollectiongetQueuedThreads()获取等待在同步队列上的线程们

3.同步队列的节点属性

属性描述
int waitStatus等待状态
Node pre前驱节点
Node next后继节点
Node nextWaiter等待队列中的后继节点,如果当前节点式共享模式,那么这个节点是SHARED常量,也就是说节点类型和等待中后继节点是公用一个字段
Thread thread获取同步状态的线程

等待状态是一个枚举,具备下列可选的值

  • CANCELLED(1)线程获取锁超时or被中断,需要从同步队列中取消中断,节点进入改状态后状态不再改变
  • SIGNAL(-1)后继节点线程处于等待状态,而当前节点的线程如果释放共享资源或者被取消会通知后继节点,使后继线程被唤醒继续执行
  • CONDITION(-2)节点在等待队列中,节点中的线程在Condition上进行等待,需要等待其他线程调用Condition的singal or singalAll进行唤醒,该节点会从等待队列移动到同步队列,进行共享资源的争夺
  • PROPAGATE(-3)表示下一次共享式同步状态的获取将无条件的传播下去
  • 0 初始状态,节点假如到同步队列时候的状态

4.AQS怎么维护同步队列

AQS中包含两个节点类型引用:头节点和尾节点。当一个线程获取到同步状态的时候,其他线程无法获取,将被放入到同步队列中,加入队列这个过程为了保证线程安全而采用CAS。同步队列遵守FIFO,头节点是获取到同步状态的线程,释放同步状态将会唤醒后继线程,后继节点获取到同步状态后将被设置为头节点

三丶ReentrantLock可重入锁

1.ReentrantLock简介

支持公平和非公平和重入的独占式锁

  • 重入表示已经获得锁的线程可以对共享资源重复加锁
  • 公平锁,支持先来后到,像在公司排队上厕所,先来的人肯定优先获取到茅坑,先来的线程肯定先获取到共享资源
  • 独占式,同一时间只允许一个线程操作共享资源

2.公平锁和非公平锁比较

公平锁在头节点释放同步资源的时候需要unpark后续节点,并切换线程执行上下文,导致效率并不如非公平锁,但是公平锁可以减少饥饿,因为非公平锁好像A在排队,A获取到共享资源需要进行唤醒和上下文切换,而导致需要更多时间,这时候流氓B刚好进厕所门,上来就是一个CAS,很快抢占了厕所这一共享资源,导致A处于饥饿——迟迟得不到厕所(共享资源)的操作资源。

3.ReentrantLock的可重入

实现可重入需要解决两个问题

  • 线程再次获得锁,锁需要去识别当前线程释放是当前占据锁的线程,如果是那么直接加锁成功
  • 锁的最终释放,加锁多少次,就需要释放多少次,完全解锁后其他线程才可以获取到锁。

第一个问题ReentrantLock通过获取当前线程和独占锁线程的`==1判断来实现,第二个问题ReentrantLock通过对AQS中的共享资源state增加和减少来实现

四丶结合ReentrantLock分析加锁解锁的流程

1.ReentranLock

ReentrantLock的公平和非公平就是由于sync引用指向了的不同实现,其lock unlock等操作也是一律交由到sync

2.ReentrantLock的非公平模式

2.1非公平加锁——lock方法

加锁的大致流程

  • 无论是非公平还是公平在加锁成功后都会通过setExclusiveOwnerThread设置当前线程为独占锁的线程,这个方法会记住当前线程,这是后面实现可重入的关键、
  • acquire 方法会调用tryAcquire方法,这个方法由AQS的子类实现,NonfairSync这里会调用nonfairTryAcquire方法
2.1.1不公平的尝试获取共享资源nonfairTryAcquire

  • 如果nonfairTryAcquire返回true表示当前线程获取到了锁,那么皆大欢喜,当前线程可以继续运行

  • 返回false的情况

    • 共享资源是0,但是同一个时间多个线程抢占,当前这个线程CAS失败了
    • 共享资源不是0,当前线程也不是独占的线程这两种情况都需要继续执行AQS的acquire方法
2.1.2AQS的acquire 方法

独占模式获取共享资源,对中断不敏感,或者说不响应中断——获取共享资源失败的线程将会进入到同步队列,后续对此线程进行中断操作,线程不会从同步队列中移出

1.执行流程

2.将当前线程包装成Node加入到队列尾addWaiter

  • 快速入队

下面这段代码值得品一品

Node pred = tail;
if (pred != null) {//当前线程的前置设置为尾,这一步那么多个线程执行这一步也是无关紧要的//只是把当前节点的前置改变了,不是改变pred的next指向node.prev = pred;//CAS设置尾节点 为当前节点,这个自选操作compareAndSetTail是线程安全,同一时间只有一个线程可以设置自己为尾节点if (compareAndSetTail(pred, node)) {//注意 如果原尾节点是S,线程A设置成功 那么尾巴被修改为了A,假如A执行下面一行的时候消耗完了时间片,线程B进来了,这时候线程B拿到的tail就是A,所以不会存在线程安全问题pred.next = node;return node;}
}
  • 完整入队

!

完整入队和快速入队差不多,就是多了一个初始化的逻辑

那么为什么不直接完整入队,也许是for循环比if多更多的字节码需要执行?也许Doug Lea测试多次后发现快速入队后完整入队,比直接完整入队效率更高

3.尝试出队acquireQueued

  • 如何从自旋中退出

前继节点是头节点,头节点是当前获取到共享资源的节点,且获取共享资源tryAcquire成功

  • 挂起当前线程避免无休止的自选

自选是cpu操作,无限制的自选是很浪费cpu资源的

如果shouldParkAfterFailedAcquire放回true 表示当前线程需要被挂起,会继续执行parkAndCheckInterrupt,这个方法很简单只有两行

private final boolean parkAndCheckInterrupt() {//挂起当前线程LockSupport.park(this);//返回中断状态,并且清除中断标识return Thread.interrupted();
}

如果parkAndCheckInterrupt 返回了true 表示当前线程被中断过,并且会让外层的acquireQueued返回true,会导致acquire执行当前线程的自我中断

理解这一段代码需要对java中断机制具备一定理解

java线程中断机制
  • 调用Thread的interrupt方法

    • 如果线程处于Running状态那么只是修改Thread内部的中断标识值为true
    • 如果线程由于sleep,wait,join等方法进入等待状态,会直接抛出中断异常并清楚中断标识
    • 如果线程由于LockSupport.park进入等待状态,调用该线程的interrupt方法只会让LockSupport.park返回
  • interrupt,interrupted,isInterrupted三个方法比较

    • interrupt 见上⬆
    • interrupted 返回当前线程的中断标识并且充值中断标识
    • isInterrupted返回中断标识

我们继续说为什么当前线程在获取锁的途中被中断,需要自我中断以下

acquire的"需求":
独占模式获取共享资源,对中断不敏感,或者说不响应中断——获取共享资源失败的线程将会进入到同步队列,后续对此线程进行中断操作,线程不会从同步队列中移出

线程获取同步状态的时候被中断会发生什么——从LockSupport.park(this)中返回继续拿锁,这就是为什么说acquire的对中断不敏感。

LockSupport.park();不会抛出受检查异常,当出现被打断的情况下,线程被唤醒后,我们可以通过Interrupt的状态来判断,我们的线程是不是被interrupt的还是被unpark或者到达指定休眠时间

假如我们写如下这样的代码执行

存在一个调度线程中断了上面的线程,但是上面的线程还在抢夺锁,并且被park了,这时候上面线程的park会返回,并且清除中断标识,如果不进行自我中断,那么下面while内容还是会进行,那么我们调度线程的中断就无效了

3.ReentrantLock的公平模式

传入true获取一个公平锁

3.1公平的获取锁——lock方法

公平锁的lock方法直接调用AQS的acquire方法,上面我们分析的acquire方法它会先去调用tryAcquire,这个tryAcquire被FairSync重写

  • FairSync的tryAcquire方法
 protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();//共享状态当前空闲if (c == 0) {//前面没有节点 这就是公平是怎么实现的//且cas成功 那么拿到锁if (!hasQueuedPredecessors() &&compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//实现重入 和 公平锁一样else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0)throw new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}
}

源码没什么很难的点,就是通过判断前面时候还有节点(标识是否由线程比当前线程先到)如果没有那么再去拿锁,如果共享状态不是0且当前线程不是独占的线程那么就会执行acquireQueued方法,在acquireQueued里面自选获取锁会判断前一个节点是否是头节点且调用tryAcquire

4.释放锁

释放锁直接调用AQS的release方法,其中tryRelease方法由ReentrantLock中Sync自己实现(公平or非公平都一样)

public final boolean release(int arg) {//完全的释放资源if (tryRelease(arg)) {Node h = head;//头节点初始化的时候才为0,但是后面如果由节点加入到同步队列会把前置节点的状态设置为Singnalif (h != null && h.waitStatus != 0)//唤醒后继节点unparkSuccessor(h);return true;}return false;
}

4.1 tryRelease

protected final boolean tryRelease(int releases) {//重入了n次,当前释放m次 c=n-mint c = getState() - releases;//如果不是独占锁的线程 那么抛出异常if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();//是否完全的释放了锁boolean free = false;//只有剩下的为0 才是完全释放锁if (c == 0) {//置为truefree = true;//独占线程设置为nullsetExclusiveOwnerThread(null);}//修改statesetState(c);return free;
}

需要注意的是只有完全的释放了共享资源,在ReentrantLock里就是加锁n次解锁n次,才返回true,才会去唤醒后继节点

4.2 unparkSuccessor

private void unparkSuccessor(Node node) {int ws = node.waitStatus;if (ws < 0)compareAndSetWaitStatus(node, ws, 0);Node s = node.next;if (s == null || s.waitStatus > 0) {s = null;//从尾巴开始找到队列最前面的且需要通知的节点 为什么要从尾巴开始找?for (Node t = tail; t != null && t != node; t = t.prev)if (t.waitStatus <= 0)//大于0代表放弃了s = t;}if (s != null)//唤醒LockSupport.unpark(s.thread);
}

使用 LockSupport.unpark(s.thread)唤醒线程,这里需要品一品 Doug Lea 他为什么要从尾部开始唤醒

  • 再品入队
private Node addWaiter(Node mode) {Node node = new Node(Thread.currentThread(), mode);// Try the fast path of enq; backup to full enq on failureNode pred = tail;//快速入队要求尾节点不为空if (pred != null) {node.prev = pred;if (compareAndSetTail(pred, node)) {pred.next = node;return node;}}enq(node);return node;
}
+ 快速入队快速入队要求尾节点不为空,如果尾节点为空那么说明1. 当前没有线程竞争,锁只有一个线程再使用,直接tryAcquire就成功了,所以头和尾都没有初始化
+ 完整入队- 进入完成入队条件* 队列头和尾没有初始化* CAS失败,也就是说存在比较多的线程在执行快速入队
```
private Node enq(final Node node) {for (;;) {Node t = tail;if (t == null) { // Must initializeif (compareAndSetHead(new Node()))tail = head;} else {//假设AB两个线程现在正在抢锁node.prev = t;//CAS设置尾 当前线程A被设置为了尾if (compareAndSetTail(t, node)) {//假如A执行这一行的时候用完了时间片,轮到了B B把自己设置了尾并且B的前置是A,此时A的前置还没来得及设置//如果这个时候进行唤醒,从头开始遍历的话会发现没有后面的节点了//所以需要从尾开始,找到B,B继续往前找到A//Doug Lea 永远的神t.next = node;return t;}}}
}```
  • 为什么要从尾开始遍历

5.其他

5.1独占式尝试获取锁—— tryLock方法

这部分都是调用的nonfairTryAcquire方法,也就是是说无论是公平还是非公平都是直接不公平的获取资源。tryLock方法是直接尝试,只有当前共享资源没有被占用的时候返回true,否则false 并且是立即返回所以无论是公平还是非公平,调用这个方法都是一样的逻辑——有人占着厕所那就直接回去继续工作

5.2 独占式响应中断的获取锁——lockInterruptibly

这个方法直接调用了AQS的acquireInterruptibly(1)

public final void acquireInterruptibly(int arg)throws InterruptedException {//如果已经中断了那么抛出中断异常//Thread.interrupted() 会清除中断标识,因为抛出InterruptedException就是响应了中断,if (Thread.interrupted())throw new InterruptedException();//调用公平or非公平自己复写的方法 if (!tryAcquire(arg))//如果尝试获取共享资源失败了 那么入队,自旋的共享资源doAcquireInterruptibly(arg);
}
5.2.1 doAcquireInterruptibly

基本上和acquireQueued差不多,就是自旋时发现中断了那么抛出中断异常,注意parkAndCheckInterrupt是调用的Thread.interrupted(),会清除中断标识

个人认为private final boolean parkAndCheckInterrupt() {LockSupport.park(this);//不是interrupted 而是 isInterruptedreturn Thread.isInterrupted();}
也可以实现功能,无非使用的地方比如doAcquireInterruptibly  要先调用Thread.interrupted()然后抛出异常
并且acquire方法也不要执行自我中断
5.2.2 cancelAcquire

放弃共享资源的争抢,一般是等待超时,或者被中断后响应中断

总体上就是,如果当前节点前面右节点可以唤醒当前节点的后继节点,那么CAS设置,否则直接唤醒后面的节点,并且把自己从队列移除

5.3超时并响应中断的获取锁——tryLock(long timeout, TimeUnit unit)

直接调用了AQS的tryAcquireNanos方法

public final boolean tryAcquireNanos(int arg, long nanosTimeout)throws InterruptedException {//上来就判断下是否中断了if (Thread.interrupted())throw new InterruptedException();//尝试获取锁 (调用对应公平和非公平的方法)or doAcquireNanosreturn tryAcquire(arg) ||doAcquireNanos(arg, nanosTimeout);
}
5.3.1doAcquireNanos

大致逻辑还是那些,需要注意的是,nanosTimeout > spinForTimeoutThreshold,剩余时间大于阈值(1000)才会挂起,如果小于的化还是进行自旋,因为非常短的超时时间无法做到十分精确(挂起和唤醒也是需要时间的)如果还是进行超时等待反而会表现得不精确

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【 Grey Hack 】万金油脚本:常见端口获取shell

目录脚本源码用法效果及示例成功示例FTP &#xff08;21&#xff09;端口HTTP &#xff08;80&#xff09;端口失败示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 适用于SSH (22) 端口、FTP (21) 端口、HTTP (80) 端口、SMTP (25) 端口及3306/3307 端口。 脚本源码 if pa…

ECharts整合HT#160;for#160;Web的网络拓扑图应用

ECharts图形组件在1.0发布的时候我就已经有所关注&#xff0c;今天在做项目的时候遇到了图标的需求&#xff0c;在HT for Web上也有图形组件的功能&#xff0c;但是在尝试了下具体实现后&#xff0c;发现HT for Web的图形组件是以矢量的格式来呈现的&#xff0c;在展现上可以有…

一个月后,我们又从 MySQL 双主切换成了主 - 从!

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【 Grey Hack 】万金油脚本:常见端口获取Password

目录脚本源码用法效果及示例SSH &#xff08;80&#xff09;端口FTP &#xff08;21&#xff09;端口HTTP &#xff08;80&#xff09;端口失败示例SMTP &#xff08;25&#xff09;端口版本&#xff1a;Grey Hack v0.7.3618 - Alpha 适用于SSH (22) 端口、FTP (21) 端口、HTTP…

pygame写游戏,常用代码记录

2019独角兽企业重金招聘Python工程师标准>>> pygame 写起游戏来还是挺不错的&#xff0c;不过我也没用过别的什么东西写&#xff0c;所以也没什么发言权。 些游戏我是从这篇文章开始入门的13岁天才儿童教你写游戏 下面是一些常用的代码片段&#xff0c;记录下来&…

聊聊 C++ 中几类特殊成员函数

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

mysql 数据库定时备份 增量/全备份

echo 开始:$Begin 结束:$Last $GZDumpFile succ >> $LogFilecd $BakDir/daily/bin/rm -f * 2&#xff09;增量备份脚本&#xff08;脚本中mysql的数据存放路径是/home/mysql/data&#xff0c;具体根据自己的实际情况进行调整&#xff09;[roottest-huanqiu ~]# vim /root…

【 Grey Hack 】万金油脚本:路由器漏洞检测

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 if params.len ! 2 or params[0] "-h" or params[0] "--help" then exit("<b>Usage: "program_path.split("/")[-1]" [ip_address] […

Java开发学习(十一)----基于注解开发bean作用范围与生命周期管理

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【 Grey Hack 】万金油脚本:从路由器获取Password

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 if params.len ! 2 or params[0] "-h" or params[0] "--help" then exit("<b>Usage: "program_path.split("/")[-1]" [ip_address] […

Java的注解机制——Spring自动装配的实现原理

JDK1.5加入了对注解机制的支持&#xff0c;实际上我学习Java的时候就已经使用JDK1.6了&#xff0c;而且除了Override和SuppressWarnings(后者还是IDE给生成的……)之外没接触过其他的。 进入公司前的面试&#xff0c;技术人员就问了我关于注解的问题&#xff0c;我就说可以生成…

【一知半解】AQS

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

CentOS下Samba文件服务器的安装与配置

前言&#xff1a;文件服务器提供的服务在大多数公司或企业都会被用到&#xff0c;因为在任何的公司或企业都涉及不同职位获取不同资源文件的情况&#xff0c;这就需要根据不同职位配置相关的不同权限&#xff0c;以保证相关资源文件的安全性和保密性。一、Samba介绍&#xff1a…

Java基础软件的安装及配置及Javascript的运行

1.Jdk的安装及环境变量配置&#xff1a; &#xff08;1&#xff09;计算机-属性-高级系统设置。 &#xff08;2&#xff09;环境变量-系统变量-输入变量名JAVA_HOME-输入变量值C:\Program Files (x86)\Java\jdk1.7.0_79&#xff08;jdk安装路径&#xff09; &#xff08;3&…

【 Grey Hack 】万金油脚本:在路由器上获取shell

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 if params.len ! 2 or params[0] "-h" or params[0] "--help" then exit("<b>Usage: "program_path.split("/")[-1]" [ip_address] […

面试问题整理笔记系列 一 Java容器类

虚线框表示接口&#xff1b;实线框表示实体类&#xff1b;粗线框表示最常用的实体类&#xff1b;虚线箭头表示实现了这个接口&#xff1b;实现箭头表示类可以制造箭头所指的那个类的对象。 Collection&#xff1a;只允许在每一个位置上放一个对象。它包括“以一定顺序持有一组对…

【 Grey Hack 】反向Shell

目录调查准备反向shell反向shell提权版本&#xff1a;Grey Hack v0.7.3618 - Alpha 如图&#xff0c;本案例中目标IP尚未开放常见端口 调查 通过路由器获得目标PC的用户邮箱账号和相应的Password 所用脚本介绍&#xff1a; routerpsw 准备反向shell 在本机获得root后配置r…

阈值PSI代码

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【 Grey Hack 】万金油脚本:原地提权工具

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 metaxploit include_lib("/lib/metaxploit.so") if not metaxploit thenmetaxploit include_lib(current_path "/metaxploit.so") end if if not metaxploit then ex…

android之PackageManager简单介绍

PackageManager相关 本类API是对全部基于载入信息的数据结构的封装&#xff0c;包含下面功能&#xff1a; 安装&#xff0c;卸载应用查询permission相关信息 查询Application相关信息(application&#xff0c;activity&#xff0c;receiver&#xff0c;service&#xff0c;prov…