Há muitas respostas sobre isso, mas pode ser confuso. Eu gosto de pensar dessa maneira, e talvez ajude ?:
A programação simultânea é um código que não se importa com a ordem de execução. Java é uma linguagem ruim para programação simultânea, mas existem bibliotecas e estruturas para ajudar. O JavaScript é uma excelente linguagem para programação simultânea, e geralmente é difícil quando você deseja escrever algo que não é simultâneo (por exemplo, se você deseja forçar a ordem de execução). A programação simultânea é ótima para a programação orientada a eventos (onde a ordem de execução é determinada pelos ouvintes de eventos, como código em execução no navegador que atua quando você clica em um botão ou digita em uma caixa).
Um exemplo incluiria a criação de cem solicitações HTTP. No NodeJS, a solução mais simples é abrir todas as 100 solicitações de uma só vez com um método de retorno de chamada e, quando as respostas retornam, um método é executado a cada vez. Isso é programação simultânea. Em Ruby, a solução mais simples (mais comum) é abrir uma solicitação e manipular a resposta, abrir a próxima solicitação e manipular a resposta, etc. Para muitas solicitações, o NodeJS é mais fácil de fazer em tempo hábil, embora você precise cuidado para evitar martelar o servidor ou maximizar suas conexões de saída (fácil de fazer por engano). Você pode escrever o Ruby de maneira simultânea, mas não é assim que a maioria dos códigos do Ruby é escrita, e dói um pouco fazer isso.
Programação paralelaé um código que pode ser executado simultaneamente em vários threads ou processos. Isso permite otimizar o desempenho executando o código em várias CPUs (geralmente incluindo várias máquinas, como você faria com algo como Akka). Como o NodeJS não é multiencadeado e não há execução paralela, você não precisa se preocupar em escrever código thread-safe (e a maioria dos códigos JavaScript que eu vi não é thread-safe). Em Java, mesmo que a linguagem não torne a programação simultânea o padrão normal, a programação paralela é muito incorporada, e você frequentemente precisa se preocupar com a segurança do encadeamento. Se você estiver escrevendo um site em Java, normalmente isso será executado em um contêiner que executa cada solicitação em um thread separado na mesma memória,
Algumas das opções acima dependem do escopo e dos limites dos quais você está falando. Eu trabalho em sites. A maioria dos códigos Java que vejo não é programação simultânea. Certamente, se você diminuir o zoom o suficiente, a ordem solicitada pelo cliente não é importante, mas se você aumentar o zoom além disso, a ordem em que as coisas serão executadas será ditada pelo código. Mas o código é escrito para que as solicitações possam ser executadas em paralelo com muitos objetos compartilhados que devem ser seguros para threads.
Enquanto isso, a maioria dos códigos JavaScript que vejo é simultânea: está escrito de maneira que a ordem de execução não é importante em muitos níveis. Mas não foi escrito para oferecer suporte à execução paralela na memória compartilhada. Claro, você pode executar o mesmo código em paralelo em vários processos, mas os objetos não são compartilhados, portanto, não é uma programação paralela em nenhum sentido significativo.
Para leituras adicionais, eu realmente gosto das ilustrações na resposta superior a esta pergunta aqui: https://www.quora.com/What-are-the-differences-between-parallel-concurrent-and-asynchronous-programming