线程
线程:依赖于进程存在,线程是进程中某一个任务
进程:能够调用系统资源的独立单位
多线程的意义:提高CPU的使用率,让多个任务互相抢占CPU的执行权
知意事项:线程的执行具有随机性
使用Java语言如何实现多线程环境:Java语言不能创建系统资源,所以JDK提供了一个类:Thread类:是封装的线程类
线程有几种状态:六种状态
1) NEW:新建状态
2) RUNNABLE:就绪状态
3) BLOCKED:阻塞状态
4) WAITING:等待
5) TIMED_WAITING:超时等待
6) TERMINATED:线程死亡
多线程的实现方式一:继承自Thread类
实现方式一的步骤:
1) 自定义类,继承自Thread类
2) 在自定义的类中,重写run()方法
3) 在用户线程中创建该类对象
4) 启动线程:start()
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
//设置线程名称
mt1.setName("t1");
mt2.setName("t2");
//启动线程
mt1.start();
mt2.start();
}
}
public class MyThread extends Thread{
@Override
public void run() {
for(int x = 0;x<50;x++) {
System.out.println(this.getName()+":"+x);
}
}
}
运行结果如下:
t1:0
t2:0
t1:1
t1:2
t1:3
t1:4
t1:5
t2:1
t1:6
t2:2
t1:7
t2:3
t1:8
t2:4
t1:9
t2:5
t1:10
t2:6
t1:11
t2:7
t1:12
t2:8
t1:13
t2:9
t1:14
t2:10
t1:15
t2:11
t1:16
t2:12
t1:17
t2:13
t1:18
t2:14
t2:15
t2:16
t2:17
t2:18
t2:19
t2:20
t2:21
t2:22
t2:23
t2:24
t2:25
t2:26
t2:27
t2:28
t2:29
t1:19
t2:30
t1:20
t2:31
t1:21
t1:22
t2:32
t1:23
t2:33
t1:24
t2:34
t1:25
t2:35
t1:26
t2:36
t1:27
t2:37
t1:28
t2:38
t1:29
t2:39
t1:30
t1:31
t1:32
t1:33
t1:34
t1:35
t1:36
t1:37
t1:38
t1:39
t1:40
t1:41
t1:42
t1:43
t1:44
t1:45
t1:46
t1:47
t1:48
t1:49
t2:40
t2:41
t2:42
t2:43
t2:44
t2:45
t2:46
t2:47
t2:48
t2:49
多线程的实现方式二:实现Runnable接口
实现方式二的步骤:
1) 自定义一个类,实现Runnable接口
2) 重写接口中的run()方法
3) 在主线程中创建自定义类的对象
4) 创建Thread类对象,将上面3)的资源对象作为参数进行传递
5) 启动线程
public class RunnableDemo {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr,"张三");
Thread t2 = new Thread(mr,"李四");
//启动线程
t1.start();
t2.start();
}
}
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int x = 1;x<=30;x++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
运行结果如下:
张三:1
李四:1
张三:2
张三:3
李四:2
张三:4
李四:3
李四:4
李四:5
李四:6
李四:7
李四:8
李四:9
张三:5
张三:6
张三:7
张三:8
李四:10
张三:9
李四:11
张三:10
李四:12
李四:13
李四:14
张三:11
李四:15
张三:12
李四:16
张三:13
李四:17
张三:14
李四:18
张三:15
李四:19
张三:16
李四:20
张三:17
李四:21
张三:18
李四:22
张三:19
李四:23
张三:20
李四:24
张三:21
李四:25
张三:22
李四:26
张三:23
李四:27
张三:24
李四:28
张三:25
张三:26
张三:27
李四:29
张三:28
李四:30
张三:29
张三:30
多线程的实现方式三:线程池
实现方式三的步骤:
1) 创建线程池对象
2) 使用线程池提交异步任务
3) 关闭线程池里面的异步任务
线程池的特点:产生一个固定的可重用的线程数,线程对象创建完毕并且执行完毕,不会被
GC回收掉,而是将该线程对象再次归还到线程池中,等待下次重复利用!
弊端:使用成本要比传统的开启子线程成本大
ExecutorService:接口 线程池:不能直接实例化,所以提供工程类:Executors
public static ExecutorService newFixedThreadPool(int nThreads):创建固定的可重用的线程数的线程池!
ExecutorService 的API:
提交异步任务:
<T> Future<T> submit(Callable<T> task)
Callable:异步任务接口 :有一个抽象方法:V call() throws Exception:具体计算结果值
<T> Future<T> submit(Runnable task,T result)
void shutdown() :将之前提交的异步任务按照顺序关闭!
import java.util.concurrent.ExecutorService;
public class ThreadDemo {
public static void main(String[] args) {
//1)创建线程池对象
ExecutorService threadPool = Executors.newFixedThreadPool(2) ; //线程池中有两个线程
//2)使用线程池提交异步任务:2个 (一个异步任务就是一个线程)
threadPool.submit(new MyRunnable()) ;
threadPool.submit(new MyRunnable()) ;
//关闭线程池里面的异步任务
threadPool.shutdown();
}
}
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int x = 0 ; x < 100 ; x ++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
import java.util.concurrent.ExecutionException;
public class CallableDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建线程池对象
ExecutorService threadPool = Executors.newFixedThreadPool(2) ;
//提交异步任务
Future<Integer> f1 = threadPool.submit(new MyCallable(100)) ;
Future<Integer> f2 = threadPool.submit(new MyCallable(200)) ;
//V get():获取结果
Integer i1 = f1.get() ;
Integer i2 = f2.get() ;
System.out.println(i1);
System.out.println(i2);
//关闭线程池
threadPool.shutdown();
}
}
import java.util.concurrent.Callable;
//计算每个线程求和
public class MyCallable implements Callable<Integer> {
private int number ;
public MyCallable(int number) {
this.number = number;
}
@Override
public Integer call() throws Exception {
//定义一个结果变量
int sum = 0 ;
for(int x = 0 ; x <=number ; x ++) {
sum +=x ;
}
return sum;
}
}