public static void main(String[] args) {
//创建线程对象
TestThread3 testThread3 = new TestThread3();
//创建线程对象,通过线程对象来开启我们的线程
Thread thread = new Thread(testThread3);
thread.start();
//main线程,主线程
for (int i = 0; i < 10; i++) {
System.out.println(“我在学习–”+i);
}
}
}
//输出
我在学习–0
我在学习–1
我在学习–2
我在学习–3
我在学习–4
我在撸代码–0
我在学习–5
我在撸代码–1
我在学习–6
我在撸代码–2
我在撸代码–3
我在学习–7
我在学习–8
我在学习–9
我在撸代码–4
我在撸代码–5
我在撸代码–6
我在撸代码–7
我在撸代码–8
我在撸代码–9
继承Thread类
1.子类继承Thread 类具有多线程能力
2.启动线程:子类对象.start()
3.不建议使用:避免OOP单继承局限性
实现Runnable 接口
1.实现接口Runnable 具有多线程能力
2.启动线程:传入目标对象+Thread对象.start()
3.推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
1.首先来个赛道距离,然后要离终点越来越近
2.判断比赛是否结束
3.打印出胜利者
4.龟兔赛跑开始
5.故事中是乌龟赢了,兔子需要睡觉,所以我们模拟兔子睡觉
6.终于,乌龟赢了
package cn.bloghut.thread;
/**
-
@author by 闲言
-
@classname Race
-
@description 模拟龟兔赛跑
-
@date 2021/7/27 19:13
*/
public class Race implements Runnable {
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
//模拟兔子休息
if (Thread.currentThread().getName().equals(“兔子”) || i % 10 == 0) {
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 steps) {
if (winner != null) {//已经由胜利者了
return true;
} else {
if (steps >= 100) {
winner = Thread.currentThread().getName();
System.out.println("Winner is " + winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race, “乌龟”).start();
new Thread(race, “兔子”).start();
}
}
//结果
Winner is 乌龟
创建线程方式3:实现Callable 接口
1.实现Callable接口,需要返回值类型
2.重写call 方法,需要抛出异常
3.创建目标对象
4.创建执行服务:
5.提交执行:
6.获取结果:
7.关闭服务:
package cn.bloghut.callable;
import cn.bloghut.thread.TestThread2;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
/**
-
@author by 闲言
-
@classname TestCallable
-
@description 线程创建方式三:实现Callable即可
-
@date 2021/7/29 12:03
*/
public class TestCallable implements Callable {
private String url;//网络图片地址
private String name;//保存的文件名
public TestCallable(String url, String name) {
this.name = name;
this.url = url;
}
//下载图片线程的执行体
@Override
public Boolean call() throws Exception {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downLoader(url,name);
System.out.println(“下载了文件名为:”+name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestCallable t1 = new TestCallable(“https://img-blog.csdnimg.cn/img_convert/d8885c9a178b2fcaea732190717b516d.png”, “1.jpg”);
TestCallable t2 = new TestCallable(“https://img-blog.csdnimg.cn/img_convert/d8885c9a178b2fcaea732190717b516d.png”, “2.jpg”);
TestCallable t3 = new TestCallable(“https://img-blog.csdnimg.cn/img_convert/d8885c9a178b2fcaea732190717b516d.png”, “3.jpg”);
//1.创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
//2.提交执行
Future r1 = ser.submit(t1);
Future r2 = ser.submit(t2);
Future r3 = ser.submit(t3);
//获取结果
Boolean rs1 = r1.get();
Boolean rs2 = r2.get();
Boolean rs3 = r3.get();
//关闭服务
ser.shutdownNow();
}
}
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(“IO 异常,Downloader方法出现问题”);
}
}
}
静态代理总结:
1.真实对象和代理对象都要实现同一个接口
2.代理对象要代理真实角色
好处:
代理对象可以做很多对象做不了的事情
真实对象专注做自己的事情
package cn.bloghut.proxy;
/**
-
@author by 闲言
-
@classname StactProxy
-
@description 静态代理简单说明
-
@date 2021/7/29 12:19
*/
public class StacticProxy {
public static void main(String[