进程和线程
进程:应用程序的执行实例,有独立的内存空间和系统资源
线程:CPU调度和分派的基本单位,进程中执行运算的最小单位,可完成一个独立的顺序控制流程
多线程
什么是多线程
如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为“多线程” 多个线程交替占用CPU资源,而非真正的并行执行。
多线程好处
充分利用CPU的资源,简化编程模型,带来良好的用户体验
主线程
Thread类
Java提供了java.lang.Thread类支持多线程编程
主线程
main()方法即为主线程入口
产生其他子线程的线程
必须最后完成执行,因为它执行各种关闭动作
public static void main(String args[]) {
Thread t= Thread.currentThread();
System.out.println("当前线程是: "+t.getName());
t.setName("MyJavaThread");
System.out.println("当前线程名是: "+t.getName()); }
线程的创建和启动
在Java中创建线程的两种方式
继承java.lang.Thread类
实现java.lang.Runnable接口
使用线程的步骤
1.定义线程
2.创建线程对象
3.启动线程
4.终止线程
继承Thread类创建线程
定义MyThread类继承Thread类
重写run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程
public class MyThread extends Thread{
//重写run()方法
public void run(){
for(int i=1;i<100;i++){ System.out.println(
Thread.currentThread().getName()+":"+i);
}}}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); //启动线程
}
多个线程交替执行,不是真正的“并行”
线程每次执行时长由分配的CPU时间片长度决定
常见问题
启动线程是否可以直接调用run()方法?
只有主线程一条执行路径
多条执行路径,主线程和子线程并行交替执行
实现Runnable接口创建线程
定义MyRunnable类实现Runnable接口
实现run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程
public class MyRunnable implements Runnable{//实现Runnable接口
public void run(){run()//方法中编写线程执行的代码
for(int i=1;i<100;i++){ System.out.println(
Thread.currentThread().getName()+":"+i);
}}}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread myThread = new Thread(myRunnable);
thread.start(); //启动线程
}
比较两种创建线程的方式
继承Thread类
编写简单,可直接操作线程
适用于单继承
实现Runnable接口
避免单继承局限性
便于共享资源
推荐使用实现Runnable接口方式创建线程
小练习
需求说明:使用2种创建线程的方式,创建两个子线程,每个线程均输出20次消息数字、“你好”、线程名,观察多个线程交替执行的过程
1.实现Runnable接口创建线程
public class MyThread1 implements Runnable {
public void run() {
for (int i = 0; i <=20; i++) {
System.out.println(i+".你好,来自线程"+Thread.currentThread().getName());
}
}
}
//---------------------------------------------------------------------------------
public class Test1 {
public static void main(String[] args) {
MyThread1 mt1=new MyThread1();
Thread thread1 =new Thread(mt1,"Thread-0");
Thread thread2 =new Thread(mt1,"Thread-1");
thread1.start();
thread2.start();
}
}
2.继承Thread类的方式创建线程
public class MyThread2 extends Thread {
public MyThread2(String name){
super(name);
}
public void run(){
for (int i = 0; i < 20; i++) {
System.out.println(i+".你好,来自线程"+Thread.currentThread().getName());
}
}
}
//------------------------------------------------------------------------------
public class Test2 {
public static void main(String[] args) {
MyThread2 mt1=new MyThread2("Thread-0");
MyThread2 mt2=new MyThread2("Thread-1");
// start()方法是启动线程的方法
mt1.start();
mt2.start();
}
}
线程的状态
线程调度
线程调度指按照特定机制为多个线程分配CPU的使用权
方 法 | 说 明 |
void setPriority(int newPriority) | 更改线程的优先级 |
static void sleep(long millis) | 在指定的毫秒数内让当前正在执行的线程休眠 |
void join() | 等待该线程终止 |
static void yield() | 暂停当前正在执行的线程对象,并执行其他线程 |
void interrupt() | 中断线程 |
boolean isAlive() | 测试线程是否处于活动状态 |
线程优先级
线程优先级由1~10表示,1最低,默认优先级为5 优先级高的线程获得CPU资源的概率较大 getPriority():获取当前线程的优先级
int priority =thread.getPriority(); setPriority():设置线程优先级
thread.setPriority(8);