线程与进程
计算机中有多个独立运行的任务,每个任务对应着一个进程,每个进程又可以产生多个线程
进程:
程序的一次动态执行过程,应用程序的执行实例,一个应用有可能有多个进程,有独立的内存空间和系统资源
进程的特点:
1.进程是系统运行的基本单位
2.每一个进程都有一块独立的内存空间,一组系统资源
3.每一个进程的内部数据和状态都是完全独立的
线程:
CPU调度和分配的基本单位,线程中执行运算的最小单位,可完成一个独立的控制流程,一个进程至少有一个线程
多线程:
1,在程序中同时运行了多个线程,用来完成不同的工作,则称之为”多线程”
2,多个线程交替占用CPU的资源,而非真正的并行执行
多线程的好处:
1.充分利用CPU资源
2.简化编程模型
3.带来良好的用户体验
主线程:
特点:
1.main方法即为主线程的入口
2.产生其他子线程的进程
3.总是在程序的最后执行,因为他执行各种关闭动作
子线程:
1.run方法里面的内容就是子线程的 工作任务
2.run方法就是子线程在执行,main方法就是main线程在执行
3.子线程是由main方法创建出来的
创建方式:
继承Thread类:
特点:
1.编写简单
2.适用于单继承
实现Runnable接口:
特点:
1.避免单继承的局限性
2.便于共享资源
线程的状态:
线程的生命周期可以分为4个阶段,及线程的4种状态,分别为新生状态,可运行状态,阻塞状态和死亡状态
Thread类
Thread类支持多线程编程
Thread类常用方法:
方法 | 说明 |
---|---|
void run() | 执行任务操作的方法 |
void start() | 使该线程开始执行 |
void sleep(long millis) | 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行) |
string getname() | 返回该线程的名称 |
int getPriority() | 返回线程的优先级 |
void setPriority(int newPriority) | 更改线程的优先级 |
Thread.State getState() | 返回该线程的状态 |
Boolean isAlive() | 测试线程是否处于活动状态 |
void join() | 等待该线程终止 |
void interrupt() | 中断线程 |
void yield() | 暂停当前正在执行的线程对象,并执行其他线程 |
线程的调度
线程的优先级
线程的优先级用1~10表示,10最高,1最低,默认为5,每个优先级对应Thread类的公用静态常量
默认:public static final int NORM_PRIORITY=5 ;
最低:public static final int MIN_PRIORITY=1 ;
最高:public static final int MAX_PRIORITY=10 ;
线程的优先级用setpriority()方法更改
实现线程调度的方法
1.join()方法:使当前线程暂停执行,等待调用该方法的线程结束后再继续执行本线程
2.sleep()方法:使当前线程睡眠(停止执行)millis毫秒,线程有运行中状态进入不可运行状态,睡眠时间过后会再次进入可运行状态
3.yield()方法:让当前线程暂停执行,允许其他线程执行,但该线程仍处于不可运行状态,但不变成阻塞状态,此时系统选择其他相同或优先级更高的优先级的线程执行,若无其他相同或其他优先级跟更高的线程,则该线程继续执行
sleep方法和yield方法的区别:
sleep方法 | yield方法 |
---|---|
使线程进入阻塞状态 | 将当前线程转入暂停执行的状态 |
即使没有其他等待运行的线程,当前线程也会等待指定的时间 | 如果没有其他等待执行的线程,当前线程会马上恢复执行 |
其他等待执行的线程的机会是均等的 | 会运行优先级相同或更高的线程 |
线程的同步
方法一:同步代码块 synchronized (this)
使用:将需要锁定的代码放到synchronized代码块中
特点:
1.同一时刻自能有一个线程进入 synchronized (this)中
2.当一个线程访问一个 synchronized (this)同步代码块时,其他 synchronized (this)同步代码块也同样被锁定
3.当一个线程访问 synchronized (this)同步代码块时,其他线程可以访问该资源的非同步代码
public class Test2_1 implements Runnable {
int count=100;
int num;
@Override
public void run() {
while (true){
synchronized (this){
if (count==0){
break;
}
count--;
num++;
System.out.println(Thread.currentThread().getName()+"抢到了第"+num+"张票,还剩"+count+"张票!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
方法二:同步方法(用 synchronized 关键字修饰的方法)
public class Test3_1 implements Runnable {
int count = 100;
int num;
@Override
public void run() {
while (sale()) {
}
}
public synchronized boolean sale() {
if (count == 0) {
return false;
}
count--;
num++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了第" + num + "张票,还剩" + count + "张票!");
return true;
}
}