概述
Java使用java.lang.Thread类代表 线程,所有的线程对象都必须是 Thread类 或 子类的实例。
每个线程的作用是完成一定的任务,实际上就是执行一段程序。
构造方法
- public Thread() :分配一个新的线程对象。
- public Thread(String name) :分配一个指定名字的新的线程对象。
- public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
- public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字。
成员方法
- public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。
- public void run() :此线程要执行的任务在此处定义代码。
- public String getName() :获取当前线程名称。
- public static native void yield();
参见:https://www.malaoshi.top/show_1EF4sunKmQmf.html - public final void join()
参见:https://www.malaoshi.top/show_1EF4sl9CO0Dc.html
静态方法
- public static void sleep(long millis) :当前线程休眠 millis 毫秒(暂时停止执行)。
参见:https://www.malaoshi.top/show_1EF4stgS8Z5w.html - public static Thread currentThread() :返回对当前正在执行的线程对象的引用。
使用线程步骤
Java中通过继承Thread类来 创建 并 启动多线程 ,步骤如下:
- 定义Thread类的子类,并重写该类的
run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。 - 创建Thread子类的实例,即创建了线程对象
- 调用线程对象的
start()方法来启动该线程
优缺点
优点:最为简单
缺点:由于java只能继承一个类,也就是说,继承Thread类后,不能再继承其他的类
方法run() 没有返回值,不能抛出异常
案例-模拟迅雷下载
传统下载方式
public static void main1(String[] args) {
//模拟下载过程
String name = "孤注一掷.mp4";
for (int i = 0 ; i<100 ; i++){
System.out.println("下载"+name+",进度:"+i+"%");
try {
// 休眠200ms,让他慢慢运行
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("下载 "+name+" 完成!");
name = "封神榜.mp4";
for (int i = 0 ; i<100 ; i++){
System.out.println("下载"+name+",进度:"+i+"%");
try {
// 休眠200ms,让他慢慢运行
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("下载 "+name+" 完成!");
}
多线程方式
/**
* 线程类
*/
public class Xunlei extends Thread{
/**
* 下载文件名
*/
private String name;
/**
* 实例化时需要传入下载文件名
* @param name
*/
public Xunlei(String name){
this.name = name;
}
/*
在该方法中编写多线程的代码,通常比较耗时的代码
*/
@Override
public void run() {
for (int i = 0 ; i<100 ; i++){
System.out.println("下载"+name+",进度:"+i+"%");
try {
// 休眠200ms,让他慢慢运行
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("下载 "+name+" 完成!");
}
}
启动线程:
public static void main(String[] args) {
Xunlei gu = new Xunlei("孤注一掷.mp4");
Xunlei feng = new Xunlei("封神榜.mp4");
Xunlei su = new Xunlei("速度与激情9.mp4");
// 调用Thread类的start() 方法,启动该线程
gu.start();
feng.start();
su.start();
}
例子
多线程
定义子线程:
//创建一个Thread类的子类
public class MyThread extends Thread{
//定义指定线程名称的构造方法
public MyThread(String name) {
//调用父类的String参数的构造方法,指定线程的名称
super(name);
}
//在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)
@Override
public void run() {
for (int i = 0; i <2000 ; i++) {
System.out.println(this.getName()+"-"+i);
}
}
}
测试类:
public class ThreadTestMain {
public static void main(String[] args) {
MyThread mt=new MyThread("第1个线程");
MyThread mt2=new MyThread("第2个线程");
mt.start();
mt2.start();
//在主方法中执行for循环
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName()+"-"+i);
}
}
}
执行结果如下:
main-41
main-42
main-43
第1个线程-0
第2个线程-0
第1个线程-1
main-44
第1个线程-2
第2个线程-1
第1个线程-3
线程的执行顺序,一般不可控制,是由操作系统调度