创建线程方法一
-
自定义线程类继承Thread类
-
重写run()方法,编写线程执行体
-
创建线程对象,调用start()方法启动线程
package com.kuang.ThreadLesson;
//线程开启不一定立即执行,由CPU调度执行
public class TestThread01 extends Thread{
实现多线程同步下载图片
package com.kuang.ThreadLesson;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
// 实现多线程同步下载图片
public class TestThread02 extends Thread{
private String url;
private String name;
public TestThread02(String url,String name){
this.url = url;
this.name = name;
}
// 下载图片线程的执行体
创建多线程方法二
-
定义类实现Runnable接口
-
实现run()方法
-
创建线程对象,调用start()方法启动线程
小结
-
继承Thread类
-
子类继承Thread类具备多线程能力
-
启动线程:子类对象.start()
-
不建议使用:避免OPP单继承局限性
-
-
实现Runnable接口
-
实现接口Runnable具有多线程能力
-
启动线程:传入目标对象+Thread对象.start()
-
推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
-
多个线程同时操作同一个对象
package com.kuang.ThreadLesson;
// 多个线程同时操作同一个对象
// 买火车票的例子
// 发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
public class TestThread04 implements Runnable{
//票数
private int ticketNumber = 10;
龟兔赛跑
package com.kuang.ThreadLesson;
// 模拟龟兔赛跑
public class Race implements Runnable{
// 胜利者
private static String winner;
实现Callable接口
-
实现Callable接口,需要返回值类型
-
重写call方法,需要抛出异常
-
创建目标对象
-
创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
-
提交执行:Future<Boolean> result1 = ser.submit(t1);
-
获取结果:boolean r1 = result.get();
-
关闭服务:ser.shutdownNow();
package com.kuang.Demo02;
import jdk.nashorn.internal.codegen.CompilerConstants;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
//线程创建方式三:实现Callable接口
/*
Callable的好处
1.可以定义返回值
2.可以抛出异常
*/
public class TestCallable implements Callable<Boolean> {
private String url;
private String name;
public TestCallable(String url,String name){
this.url = url;
this.name = name;
}
// 下载图片线程的执行体