线程的创建
创建线程-Thread
1.创建线程TestThread1 观察主线程和run线程体的运行结果 (顺序)
//创建线程方式1:继承Thread类,重写run()方法,调用start开启线程
//总结:注意,线程开启不一定立即执行,由CPU调度执行
public class TestThread1 extends Thread {
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 200; i++) {
System.out.println("我在图书馆---"+i);
}
}
public static void main(String[] args) {
//main线程 -主线程
//创建一个线程对象
TestThread1 testThread1=new TestThread1();
//调用start()方法 开启线程
//此时这里是start方法 使主线程main和run方法线程体同时进行
//如果把start换成run方法 则会先执行完run()再执行main主方法
testThread1.start();
for (int i = 0; i < 1000; i++) {
System.out.println("我在学习多线程--"+i);
}
}
}
2.创建线程TestThread2 观察T1 T2 T3 三个顺序运行但不顺序执行
(按照方法 理应先执行t1 然后是t2 t3) 但执行结果每次都不一样 所以线程的执行顺序不一样的)
此案例需要导入lib jar包 下载地址:
http://commons.apache.org/proper/commons-io/download_io.cgi
package com.gao;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thread,实现多线程同步下载多个图片
public class TetsThread2 extends Thread {
private String url;//图片地址
private String name;//图片名称
public TetsThread2(String url,String name){
this.url=url;
this.name=name;
}
//下载图片线程的执行体
public void run(){
webDownloader webDownloader=new webDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为"+name);
}
public static void main(String[] args) {
TetsThread2 t1=new TetsThread2("https://uploadfiles.nowcoder.com/images/20190422/392538858_1555913364515_1DFB6E348B5F86DDF063259779AECF89","1.jpg");
TetsThread2 t2=new TetsThread2("https://uploadfiles.nowcoder.com/images/20190422/392538858_1555913378487_493AF0131422EB9655B98CF0AB9D5244","2.jpg");
TetsThread2 t3=new TetsThread2("https://uploadfiles.nowcoder.com/files/20200326/548380650_1585215809223_php.png","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方法出错");
}
}
}
}
3.模拟线上抢票问题
package com.gao;
//模拟线上抢票
//发现问题:多个线程操作同一资源的情况下,线程不安全,数据紊乱
public class TestThread4 implements Runnable {
//总票数
private int ticknumber =10;
public void run(){
while (true){
if (ticknumber<=0){
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->拿到了"+ticknumber--+"张票");
}
}
public static void main(String[] args) {
TestThread4 ticket=new TestThread4();
new Thread(ticket,"小明").start();
new Thread(ticket,"小王").start();
new Thread(ticket,"小红").start();
}
}
4.模拟龟兔赛跑案例
package com.gao;
//模拟龟兔赛跑
public class Race implements Runnable{
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 0; 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;
}{
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();
}
}
静态模式代理(结婚案例)
package com.gao.demo2;
//静态代理模式总结:
//真实对象和代理对象都要实现同一个接口
//代理对象需要代理真实角色
//好处:代理对象可以做很多真实对象做不了的事情
//真实对象专注做自己的事情
public class StacticProxy {
public static void main(String[] args) {
new Thread(()-> System.out.println("I love You ")).start();
new weddingCompany(new you()).HappyMarry();
you you=new you();//你要结婚
weddingCompany weddingCompany=new weddingCompany(new you());
weddingCompany.HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
//真实角色
class you implements Marry{
@Override
public void HappyMarry() {
System.out.println("Get married so Happy");
}
}
//代理角色 帮你结婚
class weddingCompany implements Marry{
//代理-->真实目标角色
private Marry target;
public weddingCompany(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();//这就是真实对象
after();
}
private void after() {
System.out.println("结婚之后,收尾款");
}
private void before() {
System.out.println("结婚之前 布置现场");
}
}
lamda 表达式
1.推导lamda表达式(从静态内部类 局部内部类 匿名内部类 简化到lamda表达式)
package com.gao.lamda;
/*
推导lamda表达式
*/
public class Testlamda1 {
//3.静态内部类
static class Like2 implements Ilike{
@Override
public void lambda() {
System.out.println("I like lamda2");
}
}
public static void main(String[] args) {
Ilike like=new like();
like.lambda();
like=new Like2();
like.lambda();
//4.局部内部类
class Like3 implements Ilike{
@Override
public void lambda() {
System.out.println(" i like lamda3");
}
}
like=new Like3();
like.lambda();
//5.匿名内部类,没有类的名称,必须借助接口或父类
like=new Ilike() {
@Override
public void lambda() {
System.out.println("i like lamda4");
}
};
like.lambda();
//6.用lamda简化
like=()->{
System.out.println("i like lamda 5");
};
like.lambda();
}
}
//1.定义一个函数接口
interface Ilike{
void lambda();
}
//2.定义实现类
class like implements Ilike{
@Override
public void lambda() {
System.out.println("I like lamda");
}
}
-
lamda表达式的从复杂到最简的简化过程
总结:/总结 //lamda表达式 只能有一行代码的情况才能简化成一行, //如果多行只能用代码块包裹 //前提还得接口必须是函数式接口(接口内只有一个方法)(此案例 接口Ilove内只有一个方法love)
package com.gao.lamda; public class Testlamda2 { public static void main(String[] args) { //1.lamda 表示简化 Ilove love=(int a) ->{ System.out.println(" i love you " +a); }; //简化1.去掉了参数类型 love=(a)-> { System.out.println(" i love you " + a); }; //简化2.简化括号 love=a-> { System.out.println(" i love you " + a); }; //简化3.简化花括号 love=a -> System.out.println("i love you -"+a); //总结 //lamda表达式 只能有一行代码的情况才能简化成一行, //如果多行只能用代码块包裹 //前提还得接口必须是函数式接口(接口内只有一个方法)(此案例 接口Ilove内只有一个方法love) love.love(520); } } interface Ilove{ void love(int a); }