Java核心API之线程(上)
1、进程的原理
1、进程是操作系统中运行的一个任务,操作系统运行的应用程序都运行在相应的进程上。
2、进程实质上是操作系统分配的一块内存区域,操作系统正是利用进程把工作划分为一些功能单元。进程中包含的一个或多个执行单元成为线程,这些线程可以共享进程的资源。
3、线程归属于一个进程并且它只能访问该进程拥有的资源,不能访问其他进程区域。当操作系统创建一个进程后,该进程会自动申请一个名为主线程或首要线程的线程。
2、线程的原理
1、线程是进程内部的一个个功能单元。
2、同类的多个线程共享一块内存空间和一组系统资源,线程本身有一个供程序执行时的堆栈。线程在切换时符合小,因此,线程有时也被称为轻负荷进程。一个进程中可以包含多个线程。
3、进程与线程的区别
1、一个进程至少有一个线程。
2、线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
3、线程在执行过程中与进程的区别在于每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
4、从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看作多个独立的应用来实现进程的调度和管理以及资源分配。
4、线程使用的场合
1、线程通常用于在一个程序中需要同时完成多个任务的情况。我们可以将每个任务定义为一个线程,是他们得以一同工作。
2、也可以用于在单一线程中可以完成,但是使用多线程可以更快的情况。比如下载文件。
5、并发原理
多个线程“同时”运行只是我们感官上的一种表现。事实上线程是并发运行的,OS将时间划分为很多时间片段(时间片),尽可能均匀分配给每一个线程,获取时间片段的线程被CPU运行,而其他线程全部等待。所以微观上走走停停的,宏观上都在运行,这种现象叫并发,但不是绝对意义上的“同时发生”。
6、线程状态
线程状态有创建状态(New),运行准备状态(Runnable),运行状态(Running),结束状态(Dead),其他都是阻塞状态,IO阻塞状态(IO Block),睡眠阻塞状态(Sleep Block),等待阻塞状态(Wait Block)。
1、使用new关键字可以进入创建状态(New),线程调用start方法进入运行准备状态(Runnable);
2、运行准备状态(Runnable)和运行状态(Running)可以相互转换,
1)、当线程在运行准备状态(Runnable)获取到时间片段进入运行状态(Running);
2)、当线程在运行状态(Running)调用sleep方法进入睡眠阻塞状态(Sleep Block),然后进入运行准备状态(Runnable)
3)、当线程在运行状态(Running)IO操作进入IO阻塞状态(IO Block),
4)、当线程在运行状态(Running)
1、创建线程,通过实现Runnable接口
如果你的类要求作为线程去执行任务,你需要实现Runnable接口。你需要完成下面三步。
1.第一步,你需要实现Runnabule接口的run()方法。这个方法提为线程提供一个入口点,你可以将业务逻辑放在这个方法内部,下面是run()方法简单的语法结构
public void run();
2.第二步,你可以用构造方法实例化一个线程对象,
Thread(Runnable threadObj,String threadName);
那么,threadObj是一个实现Runnable接口的实例,threadName是你创建的线程名称。
3.第三步,一旦你的线程对象被创建,你可以通过调用start()方法调用它,然后start()方法执行调用run()方法。下面是一个简单的语法片段,
void start();
2、实例代码如下:
package ThreadDemo;
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
}
}
3、输出结果
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-2 exiting.
Thread Thread-1 exiting.
1、创建一个线程,继承一个Tread类
第二种创建线程的方法:创建一个类继承Thread类,可以通过下面简单两步完成。这种方式更多样化,你可以在一个Thread类中处理多线程。
1.第一步,你需要在一个Thread类中重写run()方法,这个方法为类提供一个入口点,你可以把业务逻辑放在这个方法内部。下面是一个简单的run()语法
public void run()
2.第二步,一旦你创建Thread对象,你可以通过调用start()方法调用它,然后start()方法执行调用run()方法。下面是一个简单的语法片段,
void start();
2、示例2代码如下:
package ThreadDemo;
class ThreadDemo extends Thread {
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
}catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
}
public class TestThread2 {
public static void main(String args[]) {
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
ThreadDemo T2 = new ThreadDemo( "Thread-2");
T2.start();
}
}
3、运行结果如下:
Creating Thread-1
Creating Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-2 exiting.
Thread Thread-1 exiting.