程序:指令和数据的有序集合,静态概念
进程:程序的一次执行过程,动态概念。系统资源分配的单位
线程:独立执行的路径(运行程序时,即使没有创建线程后台会有多个线程,主线程,gc线程)
注意:真正的多线程是有多个CPU(多核),如服务器。模拟多线程优于切换速度很快,就会有多线程的错觉
三种创建方式:
Thread class(继承Thread类)
Runnable接口(实现Runnable接口)
Callable接口(实现Callable接口)
注意:线程开启不一定执行,由CPU调度
创建类继承自Thread类
重写run()方法
调用start()方法开启线程
public class TestThread1 extends Thread {
@Override
public void run() {
// run方法体
}
public static void main(String[] args) {
TestThread1 t1 = new TestThread1();
// 调用start()方法
t1.start();
}
}
声明类实现Runnable接口
重写run()方法
创建类对象
创建Thread时作为参数传递,调用start()方法
public class TestThread3 implements Runnable{
@Override
public void run() {
// run方法体
}
public static void main(String[] args) {
// 创建一个线程对象
TestThread3 t3 = new TestThread3();
// 线程丢入Thread类,调用start方法
new Thread(t3).start();
}
}
龟兔赛跑 - Race
StaticProxy:静态代理,Runnable实现的原理
public class StaticProxy {
public static void main(String[] args) {
// 创建对象,相当于创建实现了Runnable接口的对象
You y1 = new You();
// 相当于将对象传入Thread类并调用start方法
new WeddingCompany(y1).HappyMarry();
//可简写为: new WeddingCompany(new You()).HappyMarry();
}
}
// marry接口,相当于Runnable接口
interface Marry{
void HappyMarry();
}
// You类,相当于实现Runnable接口的类
class You implements Marry {
@Override
public void HappyMarry(){
System.out.println("你要结婚了");
}
}
// 代理角色,帮助你结婚,相当于Thread类
class WeddingCompany implements Marry{
private Marry target;
// 传入you对象,相当于有参构造Thread类
public WeddingCompany(Marry target){
this.target = target;
}
// 具体的实现细节,相当于重写Run方法
@Override
public void HappyMarry(){
before();
this.target.HappyMarry();
after();
}
private void after() {
System.out.println("结婚后,补尾款");
}
private void before() {
System.out.println("结婚前,布置现场");
}
}
函数式接口:只包含一个抽象方法的接口
lambda表达式在函数式接口中的使用:类名 对象名 = (参数类型 形参名) -> { 需要重写的语句块; };
简化重写方法的部分代码
可简化的部分:
参数类型
括号
花括号
public class Test {
public static void main(String[] args) {
Person person = (int a)-> {System.out.println("person eat" + a);};
// 1. (a)-> {System.out.println("person eat" + a);};
// 2. a-> {System.out.println("person eat" + a);};
// 3. a-> System.out.println("person eat" + a);
person.eat(1);
}
}
interface Person{
void eat(int a);
}
实现Callable接口,需要返回值
重写call()方法,需要抛出异常
创建目标对象
创建执行服务:ExecutorService ser = Executors.newFixedThreadPool()
提交执行:Future
获取结果:boolean r1 = result1.get()
关闭服务:ser.shutdownNow()
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
public class TestCallable implements Callable<Boolean> {
private String url;
private String name;
public TestCallable(String url, String name){
this.name = name;
this.url = url;
}
@Override
public Boolean call() {
// 创建 WebDownloader 对象
WebDownloader webDownloader = new WebDownloader();
// 调用downloader方法,传入
webDownloader.downloader(url,name);
System.out.println("下载了文件名为:" + name);
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 新建对象并传参 url,name
TestCallable t1 = new TestCallable("https://img2020.cnblogs.com/blog/2459624/202107/2459624-20210728230730532-2056940147.png","1.png");
TestCallable t2 = new TestCallable("https://img2020.cnblogs.com/blog/2459624/202107/2459624-20210728203411378-1829797592.png", "2.png");
TestCallable t3 = new TestCallable("https://img2020.cnblogs.com/blog/2459624/202107/2459624-20210728203430153-280296762.png","3.png");
// 创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
// 提交执行
Future<Boolean> r1 = ser.submit(t1);
Future<Boolean> r2 = ser.submit(t2);
Future<Boolean> 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.建议使用标志位--->设置一个标志位
//3.不要使用stop或者destroy等过时或JDK不建议使用的方法
public class TestStop implements Runnable{
//1.设置一个标志位
private boolean flag = true;
@Override
public void run(){
int i = 0;
while (flag){
System.out.println("run...Thread" + i++);
}
}
//2.设置一公开方法停止线程,转换标志位
public void stop() {
this.flag = false;
}
public static void main(String[] args) {
TestStop ts1 = new TestStop();
new Thread(ts1).start();
for (int i = 0; i < 200; i++) {
System.out.println("main" + i);
if (i==50){
ts1.stop();
System.out.println("Thread线程停止了");
}
}
}
}
线程休眠:sleep方法
// 模拟倒计时
// 打印系统当前时间
Thread.sleep(1000);//参数为毫秒
线程礼让:yield方法
Thread.currentThread().getName():获取当前线程的name
//测试礼让线程
// 礼让不一定成功,看CPU心情
public class TestYield {
public static void main(String[] args) {
MyYield my1 = new MyYield();
new Thread(my1,"a").start();
new Thread(my1,"b").start();
}
}
class MyYield implements Runnable {
@Override
public void run(){
System.out.println(Thread.currentThread().getName()+"线程开始");
Thread.yield(); //礼让
System.out.println(Thread.currentThread().getName()+"线程停止");
}
}
注意:线程礼让会让线程重新进入就绪状态,重新和其他线程进行资源的抢夺
强制执行:join方法
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 500; i++) {
System.out.println("vip线程来到了"+i);
}
}
public static void main(String[] args) throws InterruptedException{
TestJoin tj1 = new TestJoin();
Thread thread = new Thread(tj1);
thread.start();
// 主线程
for (int i = 0; i < 250; i++) {
if (i == 200) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("主线程"+i);
}
}
}
注意:在调用join方法前,线程是同步执行的,调用join方法后,其他方法进入阻塞状态
原文:https://www.cnblogs.com/Coline1/p/15145777.html