一,为什么要使用多线程,什么是多线程?
首先,进程:进程是系统中正在运行的一个程序,程序一旦运行就是进程。
线程:线程是进程的一个实体,是进程的一条执行路径。就是进程中的一个独立控制单元,线程在控制着进程的执行。一个进程中至少有一个进程。
多线程:一个进程中不只有一个线程。
为什么要使用多线程:
①、为了更好的利用cpu的资源,如果只有一个线程,则第二个任务必须等到第一个任务结束后才能进行,如果使用多线程则在主线程执行任务的同时可以执行其他任务,而不需要等待;
②、进程之间不能共享数据,线程可以;
③、系统创建进程需要为该进程重新分配系统资源,创建线程代价比较小;
④、Java语言内置了多线程功能支持,简化了java多线程编程。
二、使用线程的方法
1.继承Thread类:
步骤:① 定义类继承Thread;
② 复写Thread类中的run方法;
目的:将自定义代码存储在run方法,让线程运行
③ 调用线程的start方法:
该方法有两步:启动线程,调用run方法。
2.实现Runnable接口:
类必须定义一个称为run 的无参方法。
实现步骤: ① 定义类实现Runnable接口
② 覆盖Runnable接口中的run方法
将线程要运行的代码放在该run方法中。
③ 通过Thread类建立线程对象。
④ 将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程执行指定对象的run方法就要先明确run方法所属对象
⑤ 调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
三,线程状态
1、线程睡眠—sleep:
线程睡眠的原因:
线程执行的太快,或需要强制执行到下一个线程。
线程睡眠的方法:
sleep(long millis)在指定的毫秒数内让正在执行的线程休眠。 sleep(long millis,int nanos)在指定的毫秒数加指定的纳秒数内让正在执行的线程休眠。
线程睡眠的代码演示:
package yrr;
public class Sleep {
public static void main(String[] args) {
new Thread(new CountDown(),"倒计时").start();
}
}
class CountDown implements Runnable{
int time = 5;
public void run() {
while (true) {
if(time>=0) {
System.out.println(Thread.currentThread().getName()+":"+time--);
try {
//睡眠时间为1s
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2、线程让步—yield:
该方法和sleep方法类似,也是Thread类提供的一个静态方法,可以让正在执行的线程暂停,但是不会进入阻塞状态,而是直接进入就绪状态。相当于只是将当前线程暂停一下,然后重新进入就绪的线程池中,让线程调度器重新调度一次。也会出现某个线程调用yield方法后暂停,但之后调度器又将其调度出来重新进入到运行状态。
package yrr;
//线程让步
public class YieldFirst {
public static void main(String[] args) {
yieldDome y = new yieldDome();
Thread t1 = new Thread(y,"张三吃了");
Thread t2 = new Thread(y,"李四吃了");
Thread t3 = new Thread(y,"王五吃了");
t1.start();
t2.start();
t3.start();
}
}
class yieldDome implements Runnable{
int count = 20;
public void run() {
while(true) {
if(count>0) {
System.out.println(Thread.currentThread().getName()+count--+"个瓜");
if(count % 2 ==0 ) {
Thread.yield();
}
}
}
}
}