1.多线程概念
<1>并行和并发
a.并行:多个指令多核CPU上同时执行
b.并发:同一个CPU核心,交替执行多条指令
<2>进程和线程
a.进程:正在执行的程序
b.线程:线程是进程中的一个执行单元(路径),如果一个进程中包含多个线程,这个程序就是多线程程序;
如:QQ、迅雷、360、飞秋等
2.创建线程的方式
【Java的API提供了一个Thread类表示线程,创建一个Thread及其子类对象,即是线程对象】
<1>继承Thread(线程)类[继承之后不能继承其他类]
//1.继承Thread(线程)类[继承之后不能继承其他类]
public class Demo1 {
public static void main(String[] args) {
//创建线程对象
DownLoadThread dLThread1 = new DownLoadThread();
DownLoadThread dLThread2 = new DownLoadThread();
//开启线程【两条线程下载100%】
dLThread1.start();//开启方法,start为系统本地方法,JVM自动调用run方法
dLThread2.start();
}
}
//具体子类
public class DownLoadThread extends Thread {
@Override
public void run() {
//线程的执行代码[将线程封装成为对象]
for (int i = 0; i < 100; i++) {
//因为为Thread子类,所以可以直接调用getName()方法
System.out.println(getName() + "正在下载..." + i + "%");
}
}
}
打印结果:
-------------------------------------------------------------------------
Thread-0正在下载...0%
Thread-1正在下载...0%
Thread-1正在下载...1%
......
Thread-0正在下载...99%
Thread-1正在下载...99%
<2>实现Runnable接口[可以继承其他类,还可以同时实现多个接口]
//2.实现Runnable接口[可以继承其他类,还可以同时实现多个接口]
public class Demo1 {
public static void main(String[] args) {
//创建了一个线程的执行任务[参数的对象]
MyRunnable myRunnable = new MyRunnable();
//创建了一个线程对象,并把线程的执行任务[参数]传递给这个线程
//在线程启动之后,执行的就是任务[参数]里面的run方法
Thread thread1 = new Thread(myRunnable);
//开启线程
thread1.start();//开启方法,start为系统本地方法,JVM自动调用run方法
Thread thread2 = new Thread(myRunnable);
thread2.start();
}
}
//具体实现类
//Runnable执行任务
public class MyRunnable implements Runnable{
@Override
public void run() {
//线程启动后执行的代码
for (int i = 0; i < 100; i++) {
//Thread类静态方法得到当前执行的线程的对象
Thread thread = Thread.currentThread();
//再通过线程获取名称
String name = thread.getName();
System.out.println(name + "正在下载..." + i + "%");
}
}
}
打印结果:
-------------------------------------------------------------------------
Thread-0正在下载...0%
Thread-1正在下载...0%
Thread-1正在下载...1%
......
Thread-0正在下载...99%
Thread-1正在下载...99%
<3>实现Callable接口并创建实现类对象,再封装到FutureTask再传递给Thread对象[线程执行完之后有返回结果]
//实现Callable接口并创建实现类对象,再封装到FutureTask再传递给Thread对象
//[线程执行完之后有返回结果]
public class Demo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建Callable的实现类对象
// 线程开启之后需要执行FutureTask里面的run方法
// 而FutureTask里面的run方法会调用myCallable的call方法
MyCallable myCallable = new MyCallable();
//call方法会把返回值再封装到FutureTask[泛型与call方法一致]
//可以获取线程执行完毕之后的结果
FutureTask<Integer> ft = new FutureTask<>(myCallable);
//FutureTask实现了Runnable接口,所以可以传递给Thread对象
//创建Thread对象,将ft作为参数传入
Thread thread = new Thread(ft);
//开启线程
thread.start();//开启方法,start为系统本地方法,JVM自动调用run方法
//如果想获得线程执行之后的结果,在线程开启之后调用FutureTask的get方法
Integer integer = ft.get();
System.out.println(integer);
}
}
//具体实现类
//MyCallable给定FutureTask执行任务,有返回值,可以检测线程执行
public class MyCallable implements Callable<Integer>//想返回什么泛型就设置什么
{
@Override
public Integer call() throws Exception {
//1-100求和
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
return sum;
}
}
打印结果:
-------------------------------------------------------------------------
4950
2.Thread类的方法
public void setName(String name) 【设置线程的名称】
public String getName() 【 获取线程的名称】
public static Thread currentThread()【获取当前正在执行的线程对象】
public static void sleep(long time)【让线程休眠指定的毫秒值】
public void setPriority(int newPriority) 【更改线程的优先级。优先级越高,执行到的几率越大,范围:[1,10]】
public int getPriority() 【获取线程的优先级】
public void setDaemon(boolean flag)【设置线程为守护线程,当主线程停止运行,守护线程也会跟着停止运行】
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
//自定义线程睡眠
DownLoadThread dLThread = new DownLoadThread();
dLThread.setName("x小黄");
//守护线程[备胎线程]--和其他线程一起时,另一条结束它也会随之结束
//setPriority()设置优先级
dLThread.setPriority(10);
dLThread.setDaemon(true);
dLThread.start();
//getPriority()获取优先级
System.out.println(dLThread.getPriority());//优先级会最先打印
//主线程睡眠
System.out.println(Thread.currentThread().getPriority());//优先级会最先打印
for (int i = 0; i < 3; i++) {
System.out.println("睡眠前");
Thread.sleep(100);//毫秒[sleep为静态方法
System.out.println("睡醒了");
}
}
}
打印结果:
-------------------------------------------------------------------------
10
5
x小黄正在下载...98%
x小黄正在下载...99%
睡醒了
睡眠前
睡醒了