Thread类、Runnable接口
线程
线程的三种创建方式:
- Thread class 继承Thread类(重点)
- Runnable接口 实现Runnable接口(重点)
- Callable接口 实现Callable接口(了解)
创建线程方法一步骤:
- 创建一个线程类,去继承Thread类
- 这个线程类立马重写run方法
- 实例化这线程个类,用实例化的对象去调用start方法执行线程。
主线程和子线程是同时、交替运行的
继承Thread类
- 子类继承Thread类具备多线程能力
- 启动线程方式:子类对象 .start();
- 不建议使用:避免oop单继承局限性
实现Runnable接口
- 实现接口Runnable具有多线程能力
- 启动线程:传入实现类的实例化对象,到Thread类的构造方法中+.start();
- 推荐使用:避免单继承局限性,灵活方法,方便同一个对象被多个线程使用
练习代码:
一、
package www.chen.com.thread;
//创建多线程方式一,继承Thread类
public class TestThread extends Thread{
//重写run方法
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 10; i++) {
System.out.println("run方法"+i);
}
}
public static void main(String[] args) {
//创建一个线程对象,调用start方法
TestThread testThread = new TestThread();
testThread.start();
//main线程,主线程
for (int i = 0; i < 10; i++) {
System.out.println("我在学习多线程"+i);
}
}
}
二、
package www.chen.com.thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习thread,实现多线程同步下载图片
public class TestThread01 implements Runnable{
private String url1;
private String name1;
//接收主线程的传参并赋值
public TestThread01(String a,String b){
this.url1 = a;
this.name1 = b;
}
//子线程调用下载器这个类,并给下载器里的downloader方法传参
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url1,name1);
System.out.println("成功下载了图片:"+name1);
}
public static void main(String[] args) {
TestThread01 testThread01 = new TestThread01("https://www.baidu.com/img/PCpad_012830ebaa7e4379ce9a9ed1b71f7507.png","baidu.jpg");
TestThread01 testThread02 = new TestThread01("https://img.kuyv.cn/201702/27/14-52-03-73-20.jpg","laopo1.jpg");
TestThread01 testThread03 = new TestThread01("https://img.kuyv.cn/201702/27/14-48-14-53-20.jpg","laopo2.jpg");
new Thread(testThread01).start();
new Thread(testThread02).start();
new Thread(testThread03).start();
}
}
//下载器 类
class WebDownloader{
//方法
public void downloader(String url,String name){
//实现代码
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("下载器执行成功,但是编译异常");
}
}
}
三、
package www.chen.com.thread;
//创建线程方式二,实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start()方法
public class TestThread2 implements Runnable{
//重写run方法
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 20; i++) {
System.out.println("run方法"+i);
}
}
public static void main(String[] args) {
//实例化实现类
TestThread2 testThread2 = new TestThread2();
//实例化Thread这个类,将实现类的实例化对象,丢到Thread这个类的构造方法中去。
//testThread2这里叫Runnable接口的目标对象
// Thread thread = new Thread(testThread2);
// //调用start方法
// thread.start();
//简写上面的代码
new Thread(testThread2).start();
//main线程,主线程
for (int i = 0; i < 1000; i++) {
System.out.println("我在学习多线程"+i);
}
}
}
四、
package www.chen.com.thread;
//龟兔赛跑
public class Race01 implements Runnable{
private static String winner;
//设置赛道长度
@Override
public void run() {
for (int i = 0; i <= 1000; i++) {
//设置兔子睡觉的时间
//如果来的是兔子,那么每10m兔子将休息10ms
if (Thread.currentThread().getName().equals("兔子")&& i%50==0){
//sleep会报异常
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//判断比赛是否结束
boolean flag = gameOver(i);
if (flag){
break;
}
//输出谁跑了多少步
System.out.println(Thread.currentThread().getName()+"--->跑了"+i+"步");
}
}
//写一个私有方法,判断是否完成比赛
private boolean gameOver(int a) {
if (winner != null) {//如果winner不为空,那么比赛结束了
return true;
}{
if (a >= 1000) {
winner = Thread.currentThread().getName();
System.out.println("winner is: " + winner);
return true;
}
return false;
}
}
//主线程调用子线程
public static void main(String[] args) {
Race01 race01 = new Race01();
new Thread(race01,"兔子").start();
new Thread(race01,"乌龟").start();
}
}

浙公网安备 33010602011771号