Java有什么不同之处?
因为它能够有效地同时使用多个核心。
- 在Java中创建新线程是否利用了多核计算机的核心?
是的。
- 与Java相比,Python只能在同一CPU上生成线程吗?
Java可以生成在不同CPU上运行的多个线程。Java并不负责实际的线程调度。这由操作系统处理。操作系统可能会将线程重新调度到与其启动时不同的CPU上。
我不确定Python的具体细节,但我认为GIL是一些实现细节而非语言本身的内在特性1。但无论哪种情况,对于Python实现,GIL意味着在多个核上生成线程不会带来太多性能提升。如此页面所述:
"Python全局解释器锁或GIL,简单来说,是一个允许一个线程控制Python解释器的互斥锁(或锁)"
- 如果是第一种情况,使用多个线程来超过CPU的数量,Java会回到上下文切换吗?
这取决于情况。在将CPU从属于不同进程的线程之间进行切换时,需要进行完整的上下文切换。但是,在同一进程中在线程之间切换时,只需要切换(用户)寄存器即可。(虚拟内存寄存器和高速缓存不需要切换/刷新,因为线程共享相同的虚拟地址空间。)
- 如果1.是正确的,那么它与多处理有何不同?因为利用多个核心并不保证?
多线程和多进程之间的关键区别在于进程不共享任何内存。相比之下,进程中的一个线程可以看到所有其他线程的内存...除了更改何时可见的问题。
这种差异具有各种后果。
- 线程化的整个目的不就是能够使用相同的内存空间吗?
是的,这是主要目的...当您将多线程与多进程进行比较时。
如果Java确实在多线程中运行其中一些以进行并行处理...
Java支持线程的原因很多。并行性只是这些原因之一。其他包括I/O复用和简化某些编程问题。这些其他原因对Python也同样适用。
...那么[Java线程]如何共享内存呢?
硬件需要解决让所有线程看到物理内存的问题,并通过内存缓存传播更改。这很复杂。
在Java中,当线程使用共享变量/对象时,责任在程序员身上。你需要使用“volatile”变量或“synchronized”块/方法或其他确保写入和后续读取之间存在“happens before”链的内容。(否则可能会出现不可见的更改问题。)将这种责任转移给程序员允许编译器生成更少的主内存操作的代码......因此更快。缺点是,如果应用程序不遵守规则,则可能以意外的方式运行。
相比之下,在Python中,内存模型未指定,但有一个期望(数百万Python程序员)认为它会按照直觉行事;即由一个线程执行的共享变量写入将立即对其他线程可见。这很难有效地实现,同时还允许Python线程并行运行。
1-虽然GIL没有正式成为Python规范的一部分,但GIL对(未指定!)Python内存模型和Python程序员的假设的影响使其不仅仅是实现细节。 Python是否能成功发展成一种可以有效利用多个核心进行多线程处理的语言仍有待观察。