Java中的线程
创始人
2024-04-10 18:54:54
0

线程

什么是线程:

image-20221117184424814

image-20221117184429961

什么是多线程:

image-20221117184455661

学习目的:

image-20221117184751362

多线程的创建

方式一:继承Thread类

image-20221117185309899

public class MyThread{public static void main(String[] args) {Thread thread01 = new Thread01();thread01.start();for (int i = 0; i < 5; i++) {System.out.println("主线程执行输出:"+i);}}
}class Thread01 extends Thread{@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程执行输出:"+i);}}
}

image-20221117185920965

image-20221117190049789

注意:

如果用thread01.run()而不用thread01.start(),那么将还是单线程执行。

主线程任务不要放在子线程之前,否则还是单线程的情形。

方式二:实现Runnable

方式二相对于方式一来说线程类可以继承别的类。

image-20221117190714908

public class MyThread{public static void main(String[] args) {Runnable r = new MyRunnable();// r为任务对象,要交给一个线程对象去处理。Thread thread = new Thread(r);thread.start();for (int i = 0; i < 5; i++) {System.out.println("主线程输出:"+i);}}
}class MyRunnable implements Runnable{@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程输出:"+i);}}
}

image-20221117191621000

image-20221117191835605

public class MyThread{public static void main(String[] args) {Runnable r = new Runnable() {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("子线程输出:"+i);}}};// r为任务对象,要交给一个线程对象去处理。Thread thread = new Thread(r);thread.start();for (int i = 0; i < 5; i++) {System.out.println("主线程输出:"+i);}}
}

方式三:jdk5.0新增,实现Callable接口

image-20221117194327720

image-20221117194636585

public class ThreadDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建callable任务对象Callable c = new MyCallable(100);// 把callable任务对象交给FutureTask对象:是Runnable对象(实现了Runnable接口),可以交给Thread// FutureTask对象可以使用get方法得到线程返回的结果FutureTask f = new FutureTask<>(c);Thread t = new Thread();t.start();// 如果f任务没有执行完毕,则f.get()会等待,线程跑完才提取结果System.out.println(f.get());}
}
class MyCallable implements Callable{private int n;public MyCallable(int n) {this.n = n;}@Overridepublic String call() throws Exception {int sum = 0;for (int i = 1; i <= n; i++) {sum = sum + i;}return "子线程的结果为:"+sum;}
}

image-20221117210743828

image-20221117210820249

三种方式的对比

image-20221117210847107

Thread的常用方法

自定义线程名字1:

public class ThreadDemo {public static void main(String[] args) {Thread t1 = new MyThread();t1.setName("1号");t1.start();Thread t2 = new MyThread();t2.setName("2号");t2.start();// 哪个线程执行它,他就返回哪个线程(当前线程对象)。Thread ct = Thread.currentThread();// 主线程调用它,拿到主线程的名字(main)。String s = ct.getName();for (int i = 0; i < 4; i++) {System.out.println(s+"线程输出"+i);}}
}class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 4; i++) {System.out.println(Thread.currentThread().getName()+"线程输出"+i);}}
}

自定义线程名字2:

public class ThreadDemo {public static void main(String[] args) {Thread t1 = new MyThread("1号");t1.start();Thread t2 = new MyThread("2号");t2.start();// 哪个线程执行它,他就返回哪个线程(当前线程对象)。Thread ct = Thread.currentThread();// 主线程调用它,拿到主线程的名字(main)。String s = ct.getName();for (int i = 0; i < 4; i++) {System.out.println(s+"线程输出"+i);}}
}
class MyThread extends Thread {public MyThread(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 4; i++) {System.out.println(Thread.currentThread().getName()+"线程输出"+i);}}
}

线程的休眠方法:

image-20221117212849038

image-20221117213446136

image-20221117213618193

线程安全

image-20221119095621485

public class MyThread  {public static void main(String[] args) {Account account = new Account("houyiming",100000);new DrawThread(account,"小明").start();new DrawThread(account,"小红").start();}
}public class DrawThread extends Thread {private Account acc;public DrawThread(Account acc,String name){super(name);this.acc = acc;}@Overridepublic void run() {acc.drawMoney(100000);}
}public class Account {private String CardId;private int money;public Account(String cardId, int money) {CardId = cardId;this.money = money;}public Account() {}public String getCardId() {return CardId;}public void setCardId(String cardId) {CardId = cardId;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}public void drawMoney(int money){String s = Thread.currentThread().getName();if (this.money >= money){System.out.println(s+"取钱,吐出:"+money);this.money -= money;System.out.println(s+"取钱后剩余:"+this.money);}else{System.out.println(s+":余额不足 ");}}
}

线程同步

image-20221119102737039

同步代码块

image-20221119102856804

synchronized ("houyiming") { // 锁对象任意,但是要唯一。if (this.money >= money){System.out.println(s+"取钱,吐出:"+money);this.money -= money;System.out.println(s+"取钱后剩余:"+this.money);}else{System.out.println(s+":余额不足 ");}
}

image-20221119103754723

synchronized (this) {if (this.money >= money){System.out.println(s+"取钱,吐出:"+money);this.money -= money;System.out.println(s+"取钱后剩余:"+this.money);}else{System.out.println(s+":余额不足 ");}
}

同步方法

image-20221119104103874

public synchronized void drawMoney(int money){String s = Thread.currentThread().getName();if (this.money >= money){System.out.println(s+"取钱,吐出:"+money);this.money -= money;System.out.println(s+"取钱后剩余:"+this.money);}else{System.out.println(s+":余额不足 ");}
}

image-20221119104428659

Lock锁

image-20221119105424142

private final Lock lock = new ReentrantLock();public void drawMoney(int money){String s = Thread.currentThread().getName();lock.lock();try {if (this.money >= money){System.out.println(s+"取钱,吐出:"+money);this.money -= money;System.out.println(s+"取钱后剩余:"+this.money);}else{System.out.println(s+":余额不足 ");}} finally {lock.unlock();}}

线程通信

image-20221119113015779

image-20221119113645553

image-20221119151745191

线程池[重点]

image-20221119152249597

线程池实现的API、参数说明

image-20221119153032458

方式一:

image-20221119153131164

image-20221119153751331

线程池实现Runnable接口

image-20221119154045189

public class ThreadPoolDemo {public static void main(String[] args) {// 创建线程池对象ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());// 把任务交给线程池处理Runnable r = new MyRunnable();pool.execute(r);pool.execute(r);pool.execute(r);pool.execute(r);pool.execute(r);pool.execute(r);pool.execute(r);pool.execute(r);// 关闭线程池,即使任务没有完成,会丢失任务pool.shutdownNow();// 等所有任务完成之后关闭pool.shutdown();}
}
public class MyRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName()+": hello world : "+i);try {Thread.sleep(100000);} catch (Exception e) {e.printStackTrace();}}}
}

image-20221119165553873

线程池实现Callable任务

public class ThreadPoolDemo2 {public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建线程池对象ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());// 把任务交给线程池处理Future f1 = pool.submit(new MyCallable(100));Future f2 = pool.submit(new MyCallable(200));Future f3 = pool.submit(new MyCallable(300));Future f4 = pool.submit(new MyCallable(400));System.out.println(f1.get());System.out.println(f2.get());System.out.println(f3.get());System.out.println(f4.get());}
}public class MyCallable implements Callable {private int n;public MyCallable(int n){this.n = n;}public MyCallable(){}@Overridepublic String call() throws Exception {int sum = 0;for (int i = 1; i <= n; i++) {sum += i;}return Thread.currentThread().getName()+"执行"+1+"到"+n+"的结果为:"+sum;}
}

Executors工具类实现线程池

image-20221119192541768

ExecutorService pool = Executors.newFixedThreadPool(3);

image-20221119194547796

定时器

image-20221119195359305

Timer定时器

image-20221119200635717

public class TimerDemo1 {public static void main(String[] args) {Timer timer = new Timer(); // 定时器本身就是一个线程timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"执行一次");}},3000,2000);}
}

ScheduledExecutorService定时器

image-20221119200803003

public class TimerDemo1 {public static void main(String[] args) {ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);pool.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"11执行输出");try {Thread.sleep(30000);} catch (InterruptedException e) {e.printStackTrace();}}},0,2, TimeUnit.SECONDS);pool.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"22执行输出");}},0,2, TimeUnit.SECONDS);}
}

并发并行、生命周期

image-20221119204009237

image-20221119204910192
image-20221119204921360

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...