什么是多线程
对于单核cpu来说,某一时刻只能有一个线程在执行,但在宏观上我们会看到多个进程在执行,这就是微观串行,宏观上并行。现在单核的电脑基本上已经没有了。多核的电脑就可以实现微观并行。多线程编程就是为了最大限度的利用cpu资源。例如当某一个线程和外设打交道时,此时它不需要用到cpu资源,但它仍然占着cpu,其他的线程就不能利用,多线程编程就可以解决该问题。多线程是多任务处理的一种特殊形式。
如何实现多线程
当cpu是单核的时候,只能执行一个线程,
双核,四核,
如果是单核,线程调用时间比较快,可能会出现多线程并发的假象。
进程:
正在被执行的程序。
一个进程里面可能出现多个线程。
实现多线程常用的三种方法:
1)Thread
(1)继承 Thread
(2)重写run方法
(3)创建线程对象,通过start()启动线程
案例:
public class MyThread extends Thread {
@Override
public void run() {
//线程要执行的内容
for (int i = 1; i < 100; i++) {
//Thread.currentThread().getName();打印当前启用的线程名称
System.out.println(i+"------"+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
//创建并启动线程
MyThread m = new MyThread();
MyThread m1 = new MyThread();
//线程启动调用的是start方法,如果调用的是run方法则不会启动线程
//m.run();//代表普通方法的执行
//如果想实现多线程,需调用start方法
m.start();
m1.start();
}
}
2)Runnable接口
(1)实现Runnable接口
(2)重写run方法
(3)创建线程类,不能直接调用start方法,需要创建Thread类。
(4)使用new Thread(Runnable) 构造函数
(5)调用thread.start()方法启动线程
案例:
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i < 500; i++) {
System.out.println(i+"--------"+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
MyRunnable m = new MyRunnable();
Thread t = new Thread(m);
t.start();
MyRunnable m1 = new MyRunnable();
Thread t1 = new Thread(m1);
t1.start();
}
}
3)Callable接口
(1)创建Callable接口的实现类,并实现call()方法,该方法有返回值;
(2)创建Callable实现类的实例,使用FutureTask来包装Callable对象,并且也封装了call()方法的返回值;
(3)使用FutureTask作为Thread类的target创建并启动线程;
(4)调用FutureTask对象的get()方法返回子线程执行结束后的返回值。
案例:
//该线程执行完可以有返回值,返回值类型需要在在Callable<返回值类型>标明
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
//线程要执行的内容,这里为求100以内的和
int sum = 0;
for (int i = 1; i <=100 ; i++) {
sum+=i;
}
return sum;
}
public static void main(String[] args) {
//创建并启动线程
MyCallable m = new MyCallable();
//创建FutureTask对象,把实现类传过去,该类的泛型为实现类的返回值类型
FutureTask<Integer> ft = new FutureTask<Integer>(m);
//把FutureTask对象传给Thread
Thread t = new Thread(ft);
//启动线程,执行的为实现类中的call方法
System.out.println("start");
t.start();
System.out.println("end");
//如果要获取线程的返回值,需要调用下面的方法
try {
Integer sum = ft.get();//接受线程的返回值
//调用ft.get()方法时,该线程(主线程)会进入阻塞状态,只有子线程执行完毕返回结果后才会继续往下执行
System.out.println(sum);//只有t线程结束后,这行以及下边的代码才会执行
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}