一.进程和线程
1.1 进程
是指一个内存中运行的应用程序(例如:QQ音乐 、微信),每个进程都有一个独立的内存空间
1.2 线程
是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行. 一个进程最少有一个线程线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分成若干个线程
1.3线程的两种调度模式
所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。
优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度,CPU使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核新而言,某个时刻,只能执行一个线程,而 CPU的在多个线程间切换速度相对我们的感觉要快,看上去就是在同一时刻运行。 其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。
1.4 同步与异步
同步: 排队执行 , 效率低但是安全.
异步: 同时执行 , 效率高但是数据不安全.
1.5 并发与并行
并发:指两个或多个事件在同一个时间段内发生。
并行:指两个或多个事件在同一时刻发生(同时发生)
二.系统引入多进程的作用
最初的计算机是“单进程的”,计算机只能运行一个应用程序,例如第一台计算机只有DOS窗口。现代的计算机可以满足我们一边听音乐,一边玩游戏。现代的计算给我们人类感觉:多件事情一起运行。感觉是并行的(错觉)。对于单核的计算机来讲,在某一个时间点上只能做一件事情,但是由于计算机的处理速度很高,多个进程之间完成频繁的切换执行,这个切换速度使人类产生了错觉,人类的错觉是:多个进程在同时运行。 计算机引入多进程的作用:提高CPU的使用率。 重点:进程和进程之间的内存独立。
三.创建线程的三种方法与启动
3.1.1 继承Thread类
Thread类中创建线程最重要的两个方法为: public void run() public void start() 采用Thread类创建线程,只需要继承Thread,覆盖Thread中的run方法,Thread中的run方法没有抛出异常,那么子类也不能抛出异常,最后采用start方法启动线程即可
public class ThreadTest01 {
public static void main(String[] args) {
Processor p = new Processor();
p.run();
method1();
}
private static void
method1() {
System.out.println("--------method1()----------");
}
}
class Processor {
public void run() {
for (int i=0; i<10; i++) {
System.out.println(i);
}
}
}
3.1.2实现Runnable接口
其实Thread对象本身就实现了Runnable接口,但一般建议直接使Runnable接口来写多线程程序,因为接口会比类带来更多的好处,之后用到Runnable比较多。 【示例代码】
public class ThreadTest03 {
public static void main(String[] args) {
Runnable r1 = new Processor();
不能直接调用
run
Thread t1 = new Thread(r1);
启动线程
t1.start();
method1();
}
private static void
method1() {
System.out.println("--------method1()----------");
}
}
实现
Runnable
接口
class Processor implements Runnable {
实现
Runnable
中的
run
方法
public void run() {
for (int i=0; i<10; i++) {
System.out.println(i);
}
}
}
3.1.3实现Callable接口,重写call方法。
Callable接口方法有返回值,可以得到在main线程中得到返回值
import java.util.concurrent.*;
public class CallableAndFuture {
public static class CallableTest implements Callable<String> {
public String call() throws Exception { return "Hello World!";
}
}
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<String> future = threadPool.submit(new CallableTest());
try {
System.out.println("waiting thread to finish");
System.out.println(future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
四.线程的生命周期
线程的生命周期存在五个状态:
新建:采用new语句创建完成 就绪:执行start后 运行:占用CPU时间 阻塞:执行了wait语句、执行了sleep语句和等待某个对象锁,等待输入的合 终止:退出run()方法
五.线程优先级
优 先 级 主 要 分 三 种 : MAX_PRIORITY(最高级) MIN_PRIORITY(最低级) NOM_PRIORITY(标准)默认 优先级高的线程会得到的CPU时间多一些,优先执行完成
|