java学习-day4

多线程学习

一、线程简介

    进程是程序执行一次执行过程,它是一个动态的概念,是系统资源分配的单位;

    一个进程可以包含若干个线程,每个进程至少有一个线程。线程是cpu调度和执行的单位。

    很多多线程是模拟出来的,真正的多线程是指有多个cpu,多核;main()称为主线程,为程序的入口;线程会带来额外的开销;

二、线程创建

Thread、Runnable、Callable

  

 总结:线程开启不一定立即执行,由cpu调度执行

实现Runable接口,实现run方法;

启动线程:传入目标对象+Thread对象.start()

避免单继承局限性,灵活方便,方便同一个对象被多个线程使用;

三、多线程操作同一个对象

问题:多个线程同时操作一个资源情况下,可能会造成并发问题;

多线程实现龟兔赛跑:

package com.Thread;


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(1);
} 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();
}
}


扩充:Callable接口 重写call方法,需要抛出异常,可以定义返回值;四步走:

 四、静态代理

真实对象和代理对象都要实现同一个接口;

代理对象要代理真实角色;

好处:代理对象可以做很多真实对象做不了的事情,真实对象专注自己的功能;

package com.Thread;

public class staticProxy {
public static void main(String[] args) {
new Thread(()-> System.out.println("i love you")).start();
weddingCompany wedding = new weddingCompany(new You());
wedding.happyMarry();
}
}

interface Marry{
void happyMarry();
}
class You implements Marry{
@Override
public void happyMarry(){
System.out.println("**要结婚了");
}
}

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 before(){
System.out.println("布置");
}
private void after(){
System.out.println("收款");
}
}

五、Lamda表达式:避免匿名内部类定义过多   精简代码

函数式接口定义:任何接口,只包含唯一一个抽象方法,那么他就是一个函数式接口

        对于函数式接口,我们可以通过Lambda表达式来创建该接口的对象;

lambda简化过程:

package com.Thread;
// 推到lambda表达式
public class TestLambda {
//静态内部类
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");
}
}

猜你喜欢

转载自www.cnblogs.com/WingsL/p/12744257.html
今日推荐