多线程
1.1线程和进程
线程是进程的一个执行单元,一个进程中有至少有一个线程,可以有很多个线程。
多线程就是多个线程在同时执行。
1.2程序运行原理
- 分时调度
所有线程轮流使用CPU的时间,平均分配每个线程占用的cpu时间
- 抢占式调度
优先让优先级高的线程使用cpu,如果线程的优先级相同,则随机选择一个(线程随机性),Java目前使用的就是抢占式。
1.3创建多线程
- 继承Thread类
将类声明为Thread类的子类,并重写run方法,创建对象,开启线程
public class MyThread extends Thread{
@Override
public void run(){
synchronized (object) {
i++;
System.out.println("i:"+i);
try {
System.out.println("线程"+Thread.currentThread().getName()+"进入睡眠状态");
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("线程"+Thread.currentThread().getName()+"睡眠结束");
i++;
System.out.println("i:"+i);
}
}
}
start():启动线程,sleep():在指定的毫秒数内让正在执行的线程休眠
当执行start()之后,jvm就会开启一个新的线程并且调用run方法,当执行线程的任务结束时,线程在内存中就会释放,当所有的线程都结束时,进程就会结束。
获取相应的线程名字mythread.currentThread().getName()
* currentThread():返回对当前正在执行的线程对象的引用
* getName():获取该线程的名字
- 通过实现Runnable接口
实现Runable的好处:避免了单一继承的局限性,线程分为两部分,一部分是线程对象,另一部分是线程任务,继承Thread类,线程对象和线程任务耦合在一起,一旦创建了Thread类的子类,即是线程对象,又是线程任务,实现Runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型,Runnable接口对线程对象和线程任务进行解耦。
- 实现Runnable接口,并重写run方法
//1.实现runnable接口并重写run方法
class MyRunnable implements Runnable{
@Override
public void run() {
}
}
- 创建Runnable实例
MyRunnable runnable = new MyRunnable();
- 创建Thread对象
Thread thread = new Thread(runnable);
thread.start();
匿名的方法实现Runnable接口
//1.匿名实现Runnable接口并重写run方法
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
2 线程池
2.1线程池概念
线程池就是一个存在多个线程的容器,其中的线程可以重复使用,省去了重复创建线程浪费的操作,节省了资源。
- Runnable接口方法
通常,线程池都是由线程池工厂方法创建,再调用线程池中的方法获取线程。再通过线程去执行任务方法
Executors:线程池创建工厂类
public static ExecutorService newFixedThreadPool(int nThread):返回线程池对象
ExecutorService:线程池类
Future接口:用来记录线程任务执行完毕后产生的后果
使用线程池的方法:
- 创建线程池对象
- 创建Runnable接口子类对象
- 提交Runnable接口子类对象
- 关闭线程池
//创建线程池对象
ExecutorService service = Executor.newFixedThreadPool(2);
MyRunnable r = new MyRunnable();
//从线程池中获取对象,调用run方法
service.submit(r);
//关闭线程池
service.shutdown();
- Callable接口
Callable接口和Runnable接口相似,用来指定线程的任务。其中的call()方法,用来返回线程任务执行完毕后的结果,call方法可以抛出异常。
//创建线程池对象
ExecutorService service = Exector.newFixedThreadPool(2);
MyCallable call = new MyCallable();
service.submit(call)
//创建Callable子类
public class MyCallable implements Callable {
@Override
public Object call() throws Exception {
System.out.println("我要一个教练:call");
Thread.sleep(2000);
System.out.println("教练来了: " +Thread.currentThread().getName());
System.out.println("教我游泳,交完后,教练回到了游泳池");
return null;
}
}