多线程
Thread
自定义线程类继承Thread
重写run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程 线程不一定立即执行,听从CPU安排调度
package com.duoXianCheng;
/*
创建线程的方式一:继承Thread类,重写run()方法,调用start开启线程
*/
public class TextThread1 extends Thread{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 10; i++) {
System.out.println("我在学习多线程"+i);
}
}
public static void main(String[] args) {//main线程,主线程
//创建一个线程对象
TextThread1 thread1 = new TextThread1();
//调用start()方法开启线程
thread1.start();
for (int i = 0; i < 200; i++) {
System.out.println("我在练习多线程"+i);
}
}
}
package com.duoXianCheng;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/*
练习Thread,实现多线程同步下载图片
*/
public class TextThread2 extends Thread{
private String url;
private String name;
public TextThread2(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader webDownloader=new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载的文件名为"+name);
}
public static void main(String[] args) {
TextThread2 t1 = new TextThread2("https://i04piccdn.sogoucdn.com/e931046dcf5606d8","1.jpg");
TextThread2 t2 = new TextThread2("https://i02piccdn.sogoucdn.com/9c60bc1d47162616","2.jpg");
TextThread2 t3 = new TextThread2("https://i03piccdn.sogoucdn.com/497eac543ca18c4e","3.jpg");
t1.start();
t2.start();
t3.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("io异常,downloader方法出现异常");
}
}
}
Runnable
package com.duoXianCheng;
/*
创建线程方式二:实现Runnable接口,重写run()方法,执行线程需要丢入runnable接口实现类,调用方法start()
*/
public class TextThread3 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("我在使用runnable"+i);
}
}
public static void main(String[] args) {
TextThread3 textThread3 = new TextThread3();
new Thread(textThread3).run();
for (int i = 0; i < 2000; i++) {
System.out.println("未知指令runnable"+i);
}
}
}
package com.duoXianCheng;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/*
练习Thread,实现多线程同步下载图片
*/
public class TextThread2 implements Runnable{
private String url;
private String name;
public TextThread2(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader webDownloader=new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载的文件名为"+name);
}
public static void main(String[] args) {
TextThread2 t1 = new TextThread2("https://i04piccdn.sogoucdn.com/e931046dcf5606d8","1.jpg");
TextThread2 t2 = new TextThread2("https://i02piccdn.sogoucdn.com/9c60bc1d47162616","2.jpg");
TextThread2 t3 = new TextThread2("https://i03piccdn.sogoucdn.com/497eac543ca18c4e","3.jpg");
// t1.start();
// t2.start();
// t3.start();
new Thread(t1).start();
new Thread(t2).start();
new Thread(t3).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("io异常,downloader方法出现异常");
}
}
}
小结
继承Thread类
* 子类继承Thread类具备多线能力
* 启动线程:子类对象.start()
* **不建议使用:避免OOP单继承局限性**
实现Runnable接口
- 实现Runnable接口具有多线程能力
- 启动线程:传入目标对象+Thread对象.start()
- 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
多个线程操作同一个资源时产生的问题
package com.duoXianCheng;
/*
多个线程操作一个对象
买火车票的例子
// 发现问题:多个线程操作同一个资源的时候,线程不安群,数据紊乱
*/
public class TextThread4 implements Runnable {
//定义一个票数
int ticketNums=10;
@Override
public void run() {
while (true){
if (ticketNums<=0){
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->抢了第"+ticketNums--+"张票");
}
}
public static void main(String[] args) {
TextThread4 textThread4=new TextThread4();
new Thread(textThread4,"小明").start();
new Thread(textThread4,"小红").start();
new Thread(textThread4,"小黄").start();
}
}
模拟龟兔赛跑
package com.duoXianCheng;
/*
模拟龟兔赛跑
*/
public class TextThread5 implements Runnable{
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 0; i <=1000 ; i++) {
if (Thread.currentThread().getName().equals("兔子")){
try {
Thread.sleep(000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//判断比赛释放结束
boolean flg=gameOver(i);
//如果flg为真则比赛结束了
if (flg){
break;
}
System.out.println(Thread.currentThread().getName()+"跑了"+i+"米");
}
}
private boolean gameOver(int steps){
if (winner!=null){//以经存在胜利者
return true;
}{
if (steps>=1000){
winner= Thread.currentThread().getName();
System.out.println("胜利在是"+winner);
return true;
}
return false;
}
}
public static void main(String[] args) {
TextThread5 thread5 = new TextThread5();
new Thread(thread5,"兔子").start();
new Thread(thread5,"乌龟").start();
}
}
Lamda表达式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4GY8Z8H3-1613780463989)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219150130371.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MGgfvq3U-1613780463991)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219150339854.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nFSSJ7Tu-1613780463993)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219150624752.png)]
Lambda表达式的推导
package com.textLambda;
/*
推到lambda表达式
*/
public class TextLambda1 {
//静态内部类
static class Like2 implements ILike {
@Override
public void lambda() {
System.out.println("i like lambda2");
}
}
public static void main(String[] args) {
ILike like = new Like();
like.lambda();
like=new Like2();
like.lambda();
//局部内部类
class Like3 implements ILike {
@Override
public void lambda() {
System.out.println("i like lambda3");
}
}
like=new Like3();
like.lambda();
//匿名内部类 ,没有类的名称,必须借助接口或者父类
like=new ILike() {
@Override
public void lambda() {
System.out.println("i like lambda4");
}
};
like.lambda();
//使用lambda简化
like=()-> System.out.println("i like lambda5");
like.lambda();
}
}
//定义一个函数式接口
interface ILike{
void lambda();
}
//定义一个实现类
class Like implements ILike{
@Override
public void lambda() {
System.out.println("i like lambda");
}
}
package com.textLambda;
public class TextLambda2 {
public static void main(String[] args) {
ILove iLove = (int a)-> {System.out.println("i love you-->"+a);};//int 可以去掉 花括号可以去掉
iLove.love(2);
}
}
interface ILove{
void love(int a);
}
//总结
// lambda表达式之只能有一行代码的清华才能简化成一行,如果有多行,那么就用代码块包裹
// 前提是接口为函数式接口
静态代理模式
package com.textLambda;
/*
静态代理模式总结
真实对象和代理对象都要实现同一个对象
代理对象要代理真实对象
*/
public class StaticProxy {
public static void main(String[] args) {
You you=new You();
WeddingCompany wc = new WeddingCompany(you);
wc.HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
//真实角色
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("结婚了超开心");
}
}
//代理角色 婚庆公司
class WeddingCompany implements Marry{
public WeddingCompany(Marry target) {
this.target = target;
}
private Marry target;
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();
after();
}
private void after() {
System.out.println("结婚结束收钱");
}
private void before() {
System.out.println("部置现场");
}
}
线程状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1Il6r5K-1613780463997)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219162401573.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WkkvnsRC-1613780463999)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219162732726.png)]
package com.duoXianCheng.stop;
/*
测试停止线程
1.建议线程正常停止---》利用次数,不建议死循环
2.建立使用标志位--》设置一个标志位
3.不要使用stop或者destroy等过时的方法或者JDK不建议使用的方法
*/
public class TextStop implements Runnable{
public static void main(String[] args) {
TextStop st = new TextStop();
new Thread(st).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if (i==10){
st.stop1();//的调用自己写的stop()方法切换标志位,让线程停止
System.out.println("线程已停止");
}
}
}
//设置一个标识位
private boolean flg=true;
@Override
public void run() {
int i=1;
while (flg){
System.out.println("线程正在运行"+i++);
}
}
//设置一个功开的方法停止线程,转换标志位
public void stop1(){
this.flg=false;
}
}
线程休眠
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V5VUa789-1613780464000)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219170402991.png)]
每个对象都有一把锁,sleep不会释放锁
package com.duoXianCheng.stop;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
模拟倒计时
*/
public class TextSleep2 {
public static void main(String[] args) {
// try {
// tenDown();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//打印当前时间
Date date = new Date(System.currentTimeMillis());
while(true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));
date=new Date(System.currentTimeMillis());//刷新当前时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//模拟倒计时
public static void tenDown() throws InterruptedException {
int num=10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num<=0){
break;
}
}
}
}
线程礼让
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WRRCerrH-1613780464001)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219182647292.png)]
package com.duoXianCheng.stop;
/*
测试礼让线程
礼让不一定成功看CPU心情
*/
public class TextYield {
public static void main(String[] args) {
MyYield my = new MyYield();
new Thread(my,"a").start();
new Thread(my,"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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g7DnvB7z-1613780464002)(C:\Users\lcj\AppData\Roaming\Typora\typora-user-images\image-20210219183936633.png)]
package com.duoXianCheng.stop;
/*
测试join方法// 类似插队
*/
public class TextJoin implements Runnable {
public static void main(String[] args) throws InterruptedException {
TextJoin tj = new TextJoin();
Thread thread = new Thread(tj);//这里不能使用匿名方法
thread.start();
for (int i = 200; i >= 0; i--) {
System.out.println("成员"+i);
if (i==100){
thread.join();
}
}
}
@Override
public void run() {
for (int i = 1000; i >=0 ; i--) {
System.out.println("vip"+i);
}
}
}