Threading 2 |学习笔记

简介: 快速学习 Threading 2

开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构:Threading 2 】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/75/detail/15835


Threading 2

 

内容介绍
、Intrinsic Locks and Synchronization

二、Atomic Access

三、Liveness

Starvation and Livelock

、Guarded Blocks

Immutable Objects

、A Synchronized Class Example

 

一、Intrinsic Locks and Synchronization

Synchronization is built around an internal entity known as

the intrinsic lock or monitor lock.

Intrinsic locks play a role in both aspects of synchronization: enforcing exclusive access to an object's state and establishing happens-before relationships that are essential to visibility.

synchronized对 于任何对象都是内部锁监视器锁可以强制要求执行 synchronized 方法线程必须要先获得对象上的锁而且旦获得别人不能修改所以强制要求对象状态访问必须是独占式谁有锁才能访问其它他人不能访问在执行时都需要获得锁锁只有一把线程旦获取再执行操作,其它人获取不尽管一个在调用increment一个在调用 decrement锁只有一把a 获得B 获得不所以任何一个对象本身因为里面有内部锁或者监视器通过 synchronized关键字实现所有操作满足 happens-before 关系有前后顺序关系前面做执行操作后面是格式

Every object has an intrinsic lock associated with it.

By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object' S intrinsic lock before accessing

them, and then release the intrinsic lock when it's done with them.

A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.

When a thread releases an intrinsic lock, a happens-before relationship is established between that action and any subsequent acquisition of the same lock.

对象都锁关联synchronized 实现每一个线程只要想对象状态成员进行操作必须用锁旦获取线程拥有其它任何线程锁没有被释放期间只要有线程拥有锁没有任何其它线程可以再次获得锁所以只能等到线程释放锁之后,其它线程才能获取谁能获得需要靠竞争不管后面是谁获取建立 happens-before关系不存在内存不致问题

Locks In Synchronized Methods

When a thread invokes a synchronized method,

it automatically acquires the intrinsic lock for that method's object and releases it when the method returns.

The lock release occurs even if the return was caused by an uncaught exception.

You might wonder what happens when a static synchronized

method is invoked,

since a static method is associated with a class, not an object.

In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.

在对象上执行方法不是对象方法是类方法不需要创建任何对象就可以在上面调用没有任何对象只在类上只要是 synchronized要访问要获得锁但是锁不是对象一个对象都有锁类上也有锁叫类对象只要定义synchronized静态方法也不会出现问题不是没有对象没法控制个类上还有把锁如果是静态方法要求获得类上面定义 synchronized 关键字increment 方法在调用的时候要获取锁在执行过程中调用其它方法也包括C也要调用 increment它们都调用不了因为是三线程,其一个获取其它线程获取不只定义一个方法是 synchronized在类里只有一个方法是 synchronized 有没有意义比如调用 increment就没办法调用decrement执行方法线程必须要获取只有 increment 方法但是有ac线程同时想调用也会出内存不情况现在是零调用执行两次是二不做保护执行完就是一有一个就会把另外一个覆盖掉所以即使只有一个方法 increment只要方法被调用synchronized 关键字修饰也有具体意义防止 ac 同时访问它的时候把它解锁所以即使类方法也有相应锁必须获取才能调用所以类方法用 synchronized 关键字修饰也有意义

Synchronized Statements

Another way to create synchronized code is with synchronized

statements.

Unlike synchronized methods, synchronized statements must specify the object that provides the intrinsic lock:

public void addName(String name) {

synchronized(this) {

lastName = name;

nameCount++;

}

nameList.add( name);

}

In this example, the addName method needs to synchronize changes to lastName and nameCount, but also needs to avoid synchronizing invocations of other objects' methods.

synchronized 关键字直接修饰在方法上力度比较粗如果一个有好几条指令把某一个人加到列表里但是还得记住现在有多少人计数器不希望在多线程操作时候出问题所以要保证只有一个线程能放但是集合类list在java大量集合类全是线程安全有多线程再往插入之后不会有任何问题名字都会插入原来list中只有两元素a要插一个B要插一个不会有问题不会最后只插进一个ac都插到末尾不存在问题没有必要把list也同步允许 ac 多线程往里性能可以提高但是 namecount 只能线程操作否则用错把整个 addname同步namelist 在任何时候只有线程访问显得力度太粗可以用 synchronized 语句定义语句块同步synchronized语句里面有参数参数是 this 值当前对象一个对象一个namelist 线程执行到必须获取当前对象lastname 等于 name两个变量进行操作时候必须是 synchronized如果是ac线程调用 addname执行到时候只能有 a 先执行b 后执行但任何时刻只有一个能执行执行结束之后执行到底下时候ac可以同时执行所以 synchronized this后面语句块只能被同步住语句是指lastName = name;

nameCount++;

避免多线程同时做改写导致内存变量发生变化,Synchronized Statements 可以让整控制力度变得很细完全按照要求控制所以 Synchronized Statements 方法显得比较粗,Synchronized 语句显得比较细腻完全可以自己控制可以充分提高系统性能

Synchronized statements are also useful for improving concurrency with fine-

grained synchronization.

public class MsLunch {

private longc1 = 0;

private longc2= 0;

private Object lock1 = new Object();

private Object lock2 = new Object();

public void inc1() {

synchronized(lock1)

{c1++; }

}

public void inc2(){

synchronized(lock2)

{ c2++; }

}

}

Use this idiom with extreme care. You must be absolutely sure that it really is safe to interleave access of the affected fields.

传递是 this 明显在使用对象一个对象都在使用锁关联但是系统中也会允许做自定义根据自定义进行操作既然每一个对象都有内部可以控制对象个 object对象本身可以像锁Synchronized把lock1传进去当线程执行c++语句时候必须要获取 lock1上面的锁lock1本身对象对象上面 本身有内部锁获取上面锁执行即可但是 inc1inc2因为操作变量不所以在操作 C1变量和操作 C2变量可以同时执行但是如果两地方都要求对 this 进行操作对 C1操作对 C 2也不能操作所以设置不同一个是 lock1,一个是lock2,把对 C1多线程操作互相隔离开对 C2进行操作隔离开但是对 C1和对 C 2操作可以进行任何一个对象都是锁如果想定义定义一个对象未来在对象上做 Synchronized,相当于在获取只有锁住才能执行底下操作可以进行力度同步

Reentrant Synchronization

Recall that a thread cannot acquire a lock owned by another

thread.

But a thread can acquire a lock that it already owns.

Allowing a thread to acquire the same lock more than once

enables reentrant synchronization.

This describes a situation where synchronized code, directly or

indirectly, invokes a method that also contains synchronized code, and both sets of code use the same lock.

Without reentrant synchronization, synchronized code would have to take many additional precautions to avoid having a thread cause itself to block.

线程确实获取锁但是线程执行逻辑比较复杂在执行过程中有可能会要求再次获取刚才比如在this上加锁前面对 this 进行加锁之后进来执行到底下调用某一个方法方法里面又有 Synchronized 语句锁已经被获取在底下调用 Synchronized,在 A 方法里面 Synchronized this在语句里面调用 m在同一个类里定义方法M进以后也是要求 Synchronized,执行到 Synchronized this 获取当前锁锁已经被当前执行线程获取到对于执行a方法线程要想执行m必须获取类似锁锁已经有M 不认要想执行 M 当前线程必须把获取的锁释放在里再获取一次但是要想释放必须要把 M 执行完语句结束才可以如果允许一个线程不止次获取锁就是可重复锁可重复锁可能是直接或者间接原因导致必须要做动作当执行到a时候已经获取到M时候又要求获取锁如果是普通获取不到就死锁这里如果能获取能获取到必须是可重复

 

二、Atomic Access

In programming, an atomic action is one that effectively

happens all at once.

There are actions you can specify that are atomic:

Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).

Reads and writes are atomic for all variables

declared volatile (including long and double variables) ,

加锁同步跟前面的事务非常像强调原子型工程所有动作必须要次性完成再执行别动作不能在执行动作同时有其它动作插入进来做在计算机里面存储数据时候所有机器元最后操作都是按字节操作比如int类型在内存里面如果占四个字节机器做加一操作最后一个字节加看看有没有进位如果有进位要和前面字节再做加再把进位跟前面加再把进位前面加个字节全处理完加一动作才结束基础值 C 加一的动作其实在机器码层面上应该至少有四条语句比如它来自于某一个内存把内存移到寄存器里寄存器做完操作再补回来加到一起机器码不止一条不是原子型,要么都执行要么都不执行或者必须同时执行在中间不会插入插句改写比如当最后一个字节加之后用进位跟倒数第二字节做加如果这时插入操作把第二字节值改掉操作最后结果肯定是错的c++或 java 都为考虑问题做约定比如 java 对引用类型变量变量和对绝大多数基本类型变量读和写都是原子型但是 long 和 d ouble 除外long 做操作可能有问题不保证所有声明称volatile 易变易失变量全部都是原子long 和 double 也在里所以在 java 关键字里面volatile 无论是long还是 double 类型当对这种类型变量做操作做读和写操作相当于把这串字节直接全部锁死只有锁死必须在写完之后才能释放保证这一条但是 volatile 一旦做这样的动作当有多线程要求写时候会全部排开顺序执行可以保证所有线程写进东西要么全是线程写进在等另外线程执行完之后再写不可能是部分是线程另外部分是另外的线程写volatile 关键字由来

Atomic actions cannot be interleaved, so they can be used

without fear of thread interference.

However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible.

Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable

线程之间互相干扰所以用 volatile 降低线程致性错误问题因为在强制要求所有线程都必须满足 happens-before 关系

 

三、Liveness

A concurrent application's ability to execute in a timely

Manner is known as its liveness.

Deadlock

Deadlock describes a situation where two or more threads

are blocked forever, waiting for each other.

Here's an example.

Alphonse and Gaston are friends, and great believers in courtesy.

A strict rule of courtesy is that when you bow to a friend, you must remain

bowed until your friend has a chance to return the bow.

Unfortunately, this rule does not account for the possibility that two friends might bow to each other at the same time.

线程在同时访问很多临界资源时候会出现三种情况第一种情况假如有两人遇到要互相鞠躬鞠躬要求向朋友鞠躬你的朋友回鞠的时候才能把身体直起来如果两人碰到以后互相鞠躬比如 a 给 B 鞠躬在B给a回鞠的时候a 可以直升但是在 B 给 a 回鞠的时候相当于 B 给 a 鞠躬B 要直身必须 a 给 b 鞠躬如果同时鞠躬卡死互相之间都在等对方指示才能直起来

image.png

定义 friend 代码friend 里面有叫做鞠躬的函数还有礼节性动作方法是 synchronized它俩之间只能有一个被调如果另外一个被调需要一个另外一个才能调用bower 是向谁鞠躬当前对象a 要向 B 鞠躬会掉a 传递 b 在屏幕输出信息A 在里面给 B 鞠躬时b 会在上面调回鞠的动作把自身传过B 被调用 Frirnd bower 方法参数传进来AB 做动作在屏幕上看输出想回A向B鞠躬时候B会向a进行回鞠输出相应的信息

public static void main(String[] args) {

final Friend alphonse =

new Friend("Alphonse");

final Friend gaston =

new Friend("Gaston");

new Thread(new Runnable() {

public void run() { alphonse.bow(gaston); }

}).start();

new Thread(new Runnable() {

public void run() { gaston.bow(alphonse); }

}).start();

}

}

定义两一个是 Friend alphonse,一个是 Friend gaston,一个在调用 a 上面的 bow一个在调用b上面的bow一个向 a 鞠躬a 向 B 鞠躬线程调用鞠躬假设 alphonse A,gaston 是b调用 a.bow b传递下来是个参数调用 b 回鞠的动作b 同时调用 a 的动作调用 b.bow ab 调用 a 时调用 a 上面 bowbacka 调用bb调用ab 向 a 鞠躬a 向 b 回鞠a 上面的锁被 bow 方法拿到b被调用时b上面的锁用 bow 方法拿到b 的锁处于b的 bow 方法a 的锁处于 a 的 bow 方法a 要调 b 的 bowback发现 bowback 是 synchronized 要获取锁b 的锁被 bow 锁住所以只能等b 对象调  a的 bowback 时要求获取a上面的锁a 上面的锁被 bow 获 取所以 bowback 拿不到锁要等着结束之后才能拿到锁a 要想释放锁前提是完成调用调用在等 b 上的锁b释放锁必须要执行完 bow 操作要等a上的锁所以形成互等的局面一直锁在这没有办法解开

 

四、Starvation and Livelock

Starvation

Starvation describes a situation where a thread is unable to gain regular access to shared resources and is unable to make progress. This happens when shared resources are made unavailable for long periods by " greedy" threads.

不是两个在死锁有一个线程获取某一个内存变量进行访问变量被其它资源占用而且资源执行时间非常长线程上面比如 join 传值一秒线程在上面长期等待因为资源另外贪婪线程或者若干线程占有始终得不到线程线程因为设置超时或者 join 动作给设时间不够等等原因最后拿不到资源完不成任务没有任何资源导致饿死

Livelock

A thread often acts in response to the action of another thread. If the other thread's action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked they are simply too busy responding to each other to resume work.

活锁跟死锁相对应双方没有死但是前面是互相等对方释放锁但是对方都不释放锁锁死活锁是大家都能完之后还是死锁状态还是锁住状态比如有一个过道走两人但是怎么走都会碰到活锁问题没有死但是也没办法往前懂看起来忙都在响应对方但是走来走去都动不了线程出现竞争产生三个问题死锁饿死活锁

 

五、Guarded Blocks

Threads often have to coordinate their actions.

The most common coordination idiom is the guarded block.

Such a block begins by polling a condition that must be true before the block can proceed.

Suppose,for example guardedJoy is a method that must not proceed until a shared

variable joy has been set by another thread.

public void guardedJoy() {

// Simple loop guard. Wastes

// processor time. Don't do this!

while(!joy){}

System.out.println("Joy has been achieved!");

} 

协调之间的关系使用防卫的 block用代码进行控制,guardedJoy 方法等条件为 false条件为 true时才等到只要没达到就一直在做但是这种方式虽然能满足条件只有条件达到才能相应的事情在上面可以加超时超市一旦到达把持有释放掉可以让对方可以拿到锁把锁解开但是 cpu 什么也没做空转所以方式并不好适当改进

A more efficient guard invokes Object.wait to suspend the

current thread.

The invocation of wait does not return until another thread has issued a notification that some special event may have occurred - though not necessarily the event this thread is waiting for:

public synchronized void guardedJoy() {

//This guard only loops once for each special event, which may not

// be the event we' re waiting for.

while(!joy) {

try { wait(); }

catch (InterruptedExceptione) {}

}

System.out.println("Joy and efficiency have been achieved!");

}

用 wait 方法在条件不满足时候wait 表示要释放当前持有资源释放锁线程挂起等待有线程唤醒cpu不空转挂起什么都不做挂起不占用 cpu 时间当有人唤醒时候再继续往下执行wait 会释放掉持有资源其它代码里面一旦 joy 变成 truenotifyall通知所有出于规定等待锁所有线程只要不是假如被唤醒是因为其它通知被唤醒但是唤醒之后还是要在里因为是循环如果不是 true 继续等旦到把joy设置成ture 唤醒notify 方法是组合使用实现guardedjoy 只要在一个对象上就调用避免 cpu 被空转运行

Let's use guarded blocks to create a Producer-Consumer

application.

This kind of application shares data between two threads:

the producer, that creates the data, and the consumer, that does something with it.

The two threads communicate using a shared object.

Coordination is essential:

the consumer thread must not attempt to retrieve the data before the producer thread has delivered it,

and the producer thread must not attempt to deliver new data if the

consumer hasn't retrieved the old data.

生产者和消费者之间模拟程序两个线程在共享对象比如改写状态改写之后消费者才能够消费临界资源只有一个状态生产者改写状态消费者消费在生产者没有改写状态时消费者消费不到如果生产者改写状态消费者没有消费生产者不允许再次生产直接抹掉消费者不能生产者发送新状态之前获取里面数据而生产者也是一样新数据如果没有被 consumer拿走之前 consumer 不能又把更新数据覆盖

image.png

drop 工作给消费者发送消息里面有字符串类型的变量消息里面有标示它的状态是不是当前 drop里面message 是空表示有没有被消费过设置成 true看看里面是不是为空如果为空等如果不为空把它设置为空消息拿走一旦设置成空notifyall等着变成空线程可以得到通知可以检查是不是空

image.png

检查 empty 是不是为空如果不为空等如果一直为空把消息放进去同时把状态改现在不为空再发通知出让所有等待线程知道状态发生变化检查是不是达到想要状态这是自身写法 drop 的写法不能有人在放同时另外的线程再取

image.png

传递进来 drop开始动作随机的睡眠时间零到五秒之间输入一条信息先放进一条消息睡眠时间零到五秒再放

image.png

通过 consumer 传递 drop从里面取消息随机睡眠多长时间只要取出的消息不断的 done等到取到done结束第一次 producer 在 dropput一进去检查 emptytrue条件不满足一直往下发消息获取通知所有线程empty 不是空有一条消息在里面假设在这个过程中没有人收到消息producer 放 第二条消息第二条消息进来之后会发现 emptyfalse循环满足条件被挂起等别人唤醒所以 true 等于挂在consumer进去取empty 不为空notifyallproducer 挂起被恢复出来继续循环已经为空所以不满足条件再往下制成不为空取走以后为不为空把新消息塞进去如果 take 一条指令之后没有新消息进来又想 take 第二条没有被改写所以两边可以保证不会出现连续两次都能发消息或者连续两次都能取消息的情况假设在改写完notify之后通知线程被恢复恢复以后可以继续支持方法组合实现 pv 操作

public class ProducerConsumerExample {

public static void main(String[] args) {

Drop drop = néw Drop{};

(new Thread(new Producer(drop))).start(); :

(new Thread(new Consumer(drop))).start();

}} 

真正例子是创建 dropdrop 分别传递给producer 和 consumer 线程启动会看到执行的效果

 

六、Immutable Objects

An object is considered immutable if its state cannot change

after it is constructed.

Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.

Immutable objects are particularly useful in concurrent

applications.

Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

在代码里面有producerconsumer代码一样producerconsumer的例子在启动线程在收发线程的时候会非常整齐发和收收发时间比较长次要等好几秒输到 done 就终止了没有再输出一发一收没有错乱开

An object is considered immutable if its state cannot change

after it is constructed.

Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.

Immutable objects are particularly useful in concurrent

applications.

Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

所有问题都是因为在改写对象值导致多线程共享对象状态时候改写搞乱变成致性出问题如果所有对象都不允许变化没有问题真正设计出类是不能改写的要创建新的对象对象里面属性希望改写成数据对象旦创建不能变只能靠通过创建新方式达到想要带有想要特征状态对象出来对象本身不能改不可变对象来创建

Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object  as  opposed to updating an object in place.

The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects.

These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption.

创建对象要花掉很大代价java 内存是第一代上面互相之间对象有引用垃圾回收机制在考察它们之间的引用关系如果发现没有外部引用的时候可以直接移除掉如果有引用关系内存满之后之后搬到老代里所以搬进去的动作上内存满并且有新创建请求过来可能会执行动作创建对象代价比较有人比较反感这种方式但实际上创建对象影响在现代机器上面不会那么大首先对象都比较小次现在占用内存会比较多真正碰上垃圾回收情况会比较少所以可以忽略保证绝对安全对象

 

七、A Synchronized Class Example

image.png

定义对象 SynchronizedRGB有红绿蓝三通道通道值都在零到二五五之间初始化时候传递三值以及颜色名字比如品红或者天蓝等等

image.png

set 方法先检查值是否在合理范围内Synchronized设颜色分别是什么get 也是 Synchronized获取名字把颜色反转全部都是用 Synchronized 关键词处理

SynchronizedRGB must be used carefully to avoid being seen in an inconsistent state.

Suppose, for example, a thread executes the following code:

SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black");

int myColorInt = color.getRGB0; //Statement 1

String myColorName = color.getName0); //Statement 2

If another thread invokes color.set after Statement 1 but before Statement 2, the value of myColorInt won't match the value of myColorName. To avoid this

outcome, the two statements must be bound together:

synchronized (color) {

int myColorInt = color.getRGB();

String myColorName = color.getName();

}

This kind of inconsistency is only possible for mutable objects it will not be an issue for the immutable version of SynchronizedRGB.

demo 创建对象调 demo 方法开线程先获取颜色睡一秒之后打印内容线程睡一秒直接往下进行匿名的线程类定义一下启动的时候先输出颜色是什么睡一秒的同时定义线程2,把颜色内容改写线程2启动线程1和线程2都启动线程1输出值睡一秒线程2把颜色给改写成 scarlet纯红绿和蓝都是零动作是先执行所以取出来开始默认值秒之后打印颜色的名字因为t2已经设置过可以看到结果颜色是零但是颜色名字是雪红色问题出在颜色虽然是scarlet但是 get 方法执行完锁就被释放线程过程中有另外线程进来调set确实没有违反 Synchronized 关键要求获取锁的动作但是因为线程了一另外再次获取 getname 的时候中间已经被别人给改即使全部用 Synchronized 关键字做控制仍然有问题仍然潜在会爆出问题所以最好方法让颜色是不可变版本

相关文章
|
13天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
5天前
|
云安全 人工智能 安全
Dify平台集成阿里云AI安全护栏,构建AI Runtime安全防线
阿里云 AI 安全护栏加入Dify平台,打造可信赖的 AI
|
12天前
|
人工智能 自然语言处理 自动驾驶
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
|
8天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
776 23
|
7天前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
497 37
|
7天前
|
机器学习/深度学习 人工智能 搜索推荐
万字长文深度解析最新Deep Research技术:前沿架构、核心技术与未来展望
近期发生了什么自 2025 年 2 月 OpenAI 正式发布Deep Research以来,深度研究/深度搜索(Deep Research / Deep Search)正在成为信息检索与知识工作的全新范式:系统以多步推理驱动大规模联网检索、跨源证据。
488 41
|
1天前
|
文字识别 监控 物联网
这是我写的实施一地两检的跨境高铁站旅客资料预报系统的系统架构
本文设计了一套基于IAPIS理念的高铁跨境旅客预报与边检联动系统,覆盖青青草原内地与喜羊羊特别行政区间“一地两检”场景。系统在旅客购票后即采集证件、生物特征及行程信息,通过Advance Passenger Info Checker等模块,向出发地和目的地移民管理机构实时推送数据,实现出入境许可预审。支持线上/线下购票、检票、退票全流程管控,结合面部识别、行为追踪技术监控旅客状态,防止滞留或非法通行。列车发车前进行最终核验,确保所有跨境旅客获边检许可。若旅行被中途取消,系统自动改签、退票并通知各方,保障安全与效率。(239字)