Chamamos de Motor Nativo o núcleo de execução do CaraCore PDV compilado sob compilação AOT (Ahead-of-Time). Ele roda de forma direta no processador local sem a necessidade de uma JVM (Java Virtual Machine) interpretando bytecode em tempo de execução e sem dependências externas.
O casamento desse motor nativo com os recursos modernos de concorrência é o que permite extrair máxima responsividade de hardware extremamente defasado.
A aplicação local do caixa precisa conversar com diversos periféricos físicos ao mesmo tempo: ler o leitor de código de barras, receber retornos do terminal de cartão de crédito (TEF), disparar a abertura da gaveta de dinheiro e mandar comandos para a impressora térmica de cupons.
Historicamente, cada uma dessas tarefas exigia uma thread física do sistema operacional (Thread de Plataforma). Se uma impressora térmica travar por falta de papel, a thread responsável pelo seu controle fica bloqueada esperando o retorno físico do hardware. Em computadores antigos de ponto de venda, esgotar o pool de threads do sistema significa travar a interface do operador inteira, parando o faturamento.
Para entender o impacto de concorrência na borda, veja o custo e o comportamento dessas duas tecnologias de execução paralela:
Ao usar threads virtuais, o fluxo de comunicação do caixa com os periféricos físicos e banco de dados é desacoplado das threads reais de processador (Carrier Threads), otimizando o paralelismo:
Na prática, configuramos o Spring Boot com Java 25 para despachar as leituras de hardware usando pools virtuais. Veja como executamos tarefas em paralelo (ler balança e enviar cupom para impressora) sem correr o risco de bloquear a interface principal do operador:
@Service
public class HardwareService {
public void processarOperacoesParalelas(Venda venda) {
// Cria um executor thread-safe baseado em threads virtuais
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
// Dispara leitura da balança física em background
executor.submit(() -> {
double peso = lerBalancaSerial();
venda.setPesoTotal(peso);
});
// Dispara a escrita da transação de cupom de forma simultânea
executor.submit(() -> {
enviarComandosImpressao(venda);
});
} // O bloco try fecha o executor garantindo o join implícito de todas as tarefas virtuais
}
}
Embora permitam escalar tarefas simultâneas, as threads virtuais possuem trade-offs claros que devem ser compreendidos:
No CaraCore PDV, rodando sob o Java 25, resolvemos esse gargalo adotando as Threads Virtuais (Project Loom). Diferente das threads clássicas, as threads virtuais são gerenciadas diretamente pela JVM e não pelo sistema operacional. Elas são extremamente leves (consomem poucos bytes de memória).
Quando uma thread virtual realiza uma operação de escrita em disco (SQLite) ou efetua uma chamada de rede assíncrona, a JVM detecta o bloqueio de I/O, retira temporariamente a thread virtual do núcleo físico da thread carrier e o libera para processar outras tarefas. Assim, conseguimos gerenciar centenas de tarefas concorrentes em background de forma eficiente.
Ative o suporte a Threads Virtuais no Spring Boot 3.x com `spring.threads.virtual.enabled=true`. O Spring criará instâncias de `VirtualThread` para cada requisição local. Como drivers seriais baseados em JNI/C (`jSerialComm`) causam o pinning da thread virtual à thread carrier física, encapsulamos as escritas de hardware em um pool de threads de plataforma dedicado, permitindo isolamento total de I/O e concorrência massiva.
Sistemas periféricos lentos ou travados (como gavetas emperradas ou impressoras sem papel) não congelam a tela de vendas. O operador pode continuar passando itens no teclado enquanto o suporte físico resolve a fila de cupons de papel em paralelo.