进程与线程
线程又称轻量级进程,是程序执行的最小单元,一个进程最少有一个线程,线程间通信比进程间通信更有优势,多个线程在一个进程中可以方便数据共享.注意线程的异常可能引起程序(进程)的崩溃.
线程虽然称轻量级进程,那只是对比进程来说,但开销还是很大的,要正确合理使用线程,一定要避免线程太多,造成线程上下文开销很大,从而影响程序的性能.
Windows系统多线程优于Unix/Linux,以多进程来说Unix/Linux比Windows有优势.
Java的跨平台是以针对不同平台(Windows/Linux/Macos)的虚拟机(JVM),屏蔽不同平台的差异.线程在JVM中没有直接实现而是调用不用平台的系统API创建的.Java中的一个线程对应了系统的一个线程.
线程的状态分别为:新生→就绪→运行/等待→死亡,一般我们只考虑就绪/等待/运行,可以看看下图.
如何使用系统API创建线程
在Windows系统使用系统API创建
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h> //CreateThread函数原型在Windows头文件
DWORD WINAPI func(void* p)
{
printf("func exec is ok!\n");
return 0;
}
int main(int argc, char *argv[])
{
HANDLE thread = CreateThread(NULL,0,func,NULL,0,NULL);
system("pause");
CloseHandle(thread);
return 0;
}
在Linux系统使用API创建线程
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void *args)
{
printf("func exec is ok!\n");
}
int main(int argc, char *argv[])
{
pthread_t pid;
pthread_create(&pid, NULL, func, NULL);
getchar();
return 0;
}
为什么要使用系统API创建线程呢?
熟悉不同平台的API,了解不同平台的差异,能够让我们知其所以然,知道了这些,就可以说Java的线程使用.
Java两种实现多线程的方式
1.继承Thread
public class MyThread extends Thread {
public MyThread(String name) {
setName(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public static void main(String[] args) {
System.out.println("main thread id:" + Thread.currentThread().getName());
System.out.println("=====================");
new MyThread("mythread1").start();
new MyThread("mythread2").start();
}
2. 实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public static void main(String[] args) {
System.out.println("main thread id:" + Thread.currentThread().getName());
System.out.println("=====================");
MyRunnable run1 = new MyRunnable();
new Thread(run1, "myrun1").start();
new Thread(run1, "myrun2").start();
}
看一下Thread源码
Thread类是精简过的,旨在了解上面说的2种方式多线程方式.
public class Thread implements Runnable {
private Runnable target;
public Thread() {
init(null, null, "Thread-", 0);
}
public Thread(String name) {
init(null, null, name, 0);
}
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
init(g, target, name, stackSize, null, true);
}
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
}
private native void start0();
public synchronized void start() {
start0();
}
@Override
public void run() {
if (target != null) {
target.run();
}
}
}