1.1 线程基本概念
基本概念:程序、进程、线程
程序(program)是为完成特定任务,用某种语言编写的一组指令的集合,即指一 段静态的代码,静态对象
进程(process)是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程:有它自身的产生,存在和消亡的过程——生命周期
1 如:运行中的QQ,运行中的MP3播放器
2 程序是静态的,进程是动态的
3 进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域
线程(thread),进程可进一步细化为线程,是一个程序内部的一条执行路径
1 若一个进程同一时间并行执行多个线程,就是支持多线程的
2 线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc)线程切换的开 销小
3 一个进程中的多个线程共享相同的内存单元/内存地址空间à它们从同一堆中分配对象,
可以访问相同的变量和对象,这就使得线程间通信更简便和高效。但多个线程操作共享 的系统资源可能就会带来安全的隐患
示例图:
1.2.1单核CPU和多核CPU的理解
1.2.2并行与并发
并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事1
1.2.3使用多线程优点
背景:以单核CPU为例,只使用单个线程先后完成多个任务(调用多个方 法),肯定比用多个线程来完成用的时间更短,为何仍需多线程呢?
多线程程序的优点:
修改
1.2.4 何事需要多线程
并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事1
背景:以单核CPU为例,只使用单个线程先后完成多个任务(调用多个方 法),肯定比用多个线程来完成用的时间更短,为何仍需多线程呢?
多线程程序的优点:
修改
需要一些后台运行的程序时
创建线程:继承 Thread 类和实现Runnable 接口等
run()方法 就等于是新线程中的main方法
启动线程 只有一种方式,就是调用线程对象的start()方法
代码实现:
public class Thread_01_Create {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建线程对象 继承方式
Thread t1=new Processor();//多态
// 启动 该线程 会自动调用run方法
t1.start();
for(int i=0;i<5;i++){
//getName(): 获取当前线程的名字
//static currentThread() : 获取当前线程对象,写在哪个类中,获取哪个线程类对象
System.out.println(Thread.currentThread().getName()+" : "+i);
}
// 但是如果我们手动调用run方法,只是方法调用而已,并不是开启新线程
// t1.run();
// 创建线程类对象 实现方式
Thread t2=new Thread(new Processor02());
t2.start();
}
}
//继承Thread类
class Processor extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for(int i=0;i<5;i++){
System.out.println(this.getName()+" : "+i);
}
}
}
//实现runnable接口
class Processor02 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
}
}
getName(): 获取当前线程的名字,默认是Thread-0 , Thread-1 依次递增
setName(): 设置线程的名字
setPriority() : 设置优先级,java有10个优先级 , 1-10
在 Thread 类中 用三个常量表示
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
默认子类继承父类优先级,而Thread的优先级是 5
static currentThread() : 获取当前线程对象,写在哪个类中,获取哪个线程类对象
static sleep() : 让当前线程进入睡眠状态,参数是睡眠的毫秒数,写在哪个类中,就睡眠哪个线程类
代码:
public class Thread_02_Method {
public static void main(String[] args) {
Thread t1=new Thread(new Processer());
t1.start();
// 设置优先级
t1.setPriority(10);
// 设置名字
t1.setName("t1");
for (int i = 0; i < 10; i++) {
try {
t1.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// currentThread 获取当前线程对象
// getName : 获取当前线程对象名字
System.out.println(Thread.currentThread().getName()+" : "+i);
}
}
}
class Processer implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// currentThread 获取当前线程对象
// getName : 获取当前线程对象名字
System.out.println(Thread.currentThread().getName()+" : "+i);
}
}
}
public static void sleep(long mills) throws InterruptedException{}
让当前线程进入睡眠状态 静态方法
interrupt() : 强制唤醒某个睡眠的线程,会抛出异常
代码:
public class Thread_03_Interrput {
public static void main(String[] args) {
Thread t1=new Thread(new Processer_02());
t1.start();
System.out.println("开始执行....");
try {
Thread.sleep(500);
System.out.println("main睡醒了");
//唤醒t1线程
t1.interrupt();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Processer_02 extends Thread {
@Override
public void run() {
try {
Thread.sleep(999999999L);
System.out.println("睡醒了");
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("被吵醒了");
}
}
}