JDK5.0之前
1、继承于Thread类创建线程
1.1、继承Thread类创建线程案例
/**
* 多线程创建方式一:继承于Thread类
* 1、创建继承于Thread类的子类
* 2、重写Thread类的run() ---->在此线程的操作在run()中
* 3、创建Thread类的子类对象
* 4、通过此对象调用start()
* 例子遍历100以内的所有偶数
*/
class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i <100 ; i++) {
if(i%2 == 0){
System.out.println(Thread.currentThread().getName()+"***"+i+"******MyThread.start*****");
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//创建Thread的子类对象
MyThread t1 = new MyThread();
//通过此对象调用start():1、启动当前线程 2、调用当前线程的run()
t1.start();
//如下操作仍是在main线程中执行
for (int i = 0; i <100 ; i++) {
if(i%2 == 0){
System.out.println(Thread.currentThread().getName()+i+"*********Main.start*******");
}
}
}
}
1.2、线程的常用方法
1、**start(): **启动当前线程 ;调用当前线程的run()
2、**run(): **通常需要重写Thread类中的此方法,将创建的创建线程需要执行的操作在此方法中声明
3、currentThread()静态返回执行当前代码的线程,在Thread子类中就是this通常用于主线程和Runnable类实现
4、getName():获取当前线程的名字
5、setName():设置当前线程的名字
6、**yield(): **静态,线程让步。
- 暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程
- 若队列中没有同优先级的线程,忽略此方法
7、join():当前某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到join()方法加入的join线程指向完为止
- 低优先级的线程也可以获得执行
8、sleep():(指定时间:毫秒):
- 令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排序
- 抛出InterruptedException异常
9、stop(): 强制线程声明期结束,不推荐使用
10、isAlive(): 返回boolan,判断线程是否还活着
1.3、线程调度及优先级的概念
线程调度的策略:
- 时间片:
- 抢占式:高优先级的线程抢占CPU
java的调度方法:
- 同优先级线程组成先进先出(先到先服务),使用时间片策略
- 对高优先级,使用优先调度的抢占式策略
线程的优先级:
线程优先级等级: MAX_PRORITY:10 MIN_PRORITY:1 MORE_PRORITY:1
涉及的方法: getPriority():返回线程的优先级 setPriority(int newPriority):改变线程的优先级
说明:
线程创建时继承父类线程的优先级
低优先级只是为获得调度的概率底,并非一定是在高优先级线程之后才被调用
2、实现Runnable接口创建线程
2.1、实现Runnable接口创建线程案例
//创建实现Runnable接口的类
class MThread implements Runnable {
@Override
//实现Runnable中的抽象方法:run()
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + "****" + i);
}
}
}
}
public class ThreadRuaable {
public static void main(String[] args) {
//3、创建类的实例对象
MThread mt = new MThread();
//4、将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
Thread thread = new Thread(mt);
//5、通过Thread类的对象调用start()
thread.start();
Thread thread2 = new Thread(mt);
thread2.start();
}
}
image.gif
JDK5.0新增线程创建方式
1、新增方式一:实现Callable接口:
1.1、Callable比Runnable的功能更强大:
1、call()可以有返回值
2、call()可以抛出异常,被外面的操作捕获,获取异常信息
3、callable是支持泛型的
4、需要借助FutureTask类,比如获取返回值
1.2、Future接口
- 可以对具体的Runnable、Callable任务的执行结果进行取消、查询是否完成,获取结果等
- FutureTask是Future接口的唯一的实现类
- FutureTask同时实现了Runnable,Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
1.3、使用Callable来使用线程计算100以内的偶数的和
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
//1、创建一个实现Callable的实现类
class Numbers implements Callable {
//2、实现call方法,将此线程需要的操作声明在call()方法中
@Override
public Object call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
if(i % 2 == 0){
System.out.println(i);
sum += i;
}
}
return sum;
}
}
public class TreadCabble {
public static void main(String[] args) {
//3、创建Callable接口的实现类的对象
Numbers numbers = new Numbers();
//4、将此Callable接口实现类的对象作为参数传递到FutureTask构造器中,创建FutureTask对象
FutureTask futureTask = new FutureTask(numbers);
//5、将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
new Thread(futureTask).start();
try {
//get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值
Object num = futureTask.get();
System.out.println(num);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
image.gif
2、新增方式二:使用线程池
背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建和销毁、实现重复利用。类似生活中的公共交通工具
好处:
提高影响速度(减少了创建新线程的时间)
降低资源消耗(重复利用线程池中线程,不需要每次都创建)
便于线程管理: corePoolSize:核心池的大小 maximunPoolSize:最大线程数 keepAliveTime:线程没有任 务时醉倒保持多长时间后会终止
线程池相关API
JDK5.0起提供了线程池相关API:ExecutorService 和 Executors
ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
网友评论