5.线程

一.使用

1.第一种方式

//mythread
public class myClass extends Thread{

    public void run(){
        for (int i = 0; i < 20; i++) {
            System.out.println("run:"+i);
        }
    }
}

//main
public class helloJava {
    public static void main(String[] args) {
        myClass th = new myClass();
        th.start();

        for (int i = 0; i < 20; i++) {
            System.out.println("main"+i);
        }
    }
}

2.第二种方式

public class myClass implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("thread:"+i);
        }
    }
}


public class helloJava {
    public static void main(String[] args){
        myClass temp = new myClass();
        Thread imp = new Thread(temp);
        imp.start();

        for (int i = 0; i < 20; i++) {
            System.out.println("main:"+i);
        }
    }
}

3.内存图解

4.thread和Runable的区别

5.匿名内部类实现线程的创建

匿名内部类的作用:

  1. 把子类继承父类,重写父类方法,创建字类对象一气呵成
  2. 把实现类实现接口,重写接口方法,创建类对象一气呵成

 

public class main {
    public static void main(String[] args) {
        //匿名内部类

        //法1
        new Thread(){
            //重写run方法
            @Override
            public void run(){
                for (int i = 0; i < 10; i++) {
                    System.out.println("th1:"+i);
                }
            }
        }.start();

        //法2
        Runnable imp =  new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("th2:"+i);
                }
            }
        };
        new Thread(imp).start();

        for (int i = 0; i < 20; i++) {
            System.out.println("main:" + i);
        }
    }
}

二.线程安全

mainTest:

public class main {
    public static void main(String[] args) {
        threadImp th = new threadImp();

        Thread th1 = new Thread(th);
        Thread th2 = new Thread(th);
        th1.start();
        th2.start();

        for (int i = 0; i < 3; i++) {
            System.out.println("main:" + i);
        }
    }
}

1.同步代码块

synchronized

public class threadImp implements Runnable {
    private int ticket = 10;
    @Override
    public void run() {
        while (true){
            synchronized (this) {
                if (ticket > 0) {
                    System.out.println("ticket:" + ticket);
                    ticket--;
                }
                if (ticket <= 0) {
                    break;
                }
            }
        }
    }
}

2.同步方法

同步方法:使用synchronized修饰的方法,就叫同步方法,保证A线程执行该方法的时候,其他线程只能再方法外等待
同步方法的锁对象是this
public class main {
    public static void main(String[] args) {
        threadImp th = new threadImp();

        Thread th1 = new Thread(th);
        Thread th2 = new Thread(th);
        th1.start();
        th2.start();

        for (int i = 0; i < 3; i++) {
            System.out.println("main:" + i);
        }
    }
}

静态同步方法:

main:

public class main {
    public static void main(String[] args) {
        //threadImp th = new threadImp();

        Thread th1 = new Thread(new threadImp());
        Thread th2 = new Thread(new threadImp());
        th1.start();
        th2.start();

        for (int i = 0; i < 3; i++) {
            System.out.println("main:" + i);
        }
    }
}

thread:

public class threadImp implements Runnable {
    private static int ticket = 10;
    @Override
    public void run() {
        fun();
    }

    public static synchronized void fun(){
        while (true){
            if (ticket > 0) {
                System.out.println("ticket:" + ticket);
                ticket--;
            }
            if (ticket <= 0) {
                break;
            }
        }
    }
}

静态方法只能访问静态成员变量;静态成员是类的所有对象中共享的成员,而不是某个对象的成员

3.锁机制

public class threadImp implements Runnable {
    private int ticket = 10;
    ReentrantLock loc = new ReentrantLock();
    @Override
    public void run() {
        fun();
    }

    public void fun(){
        loc.lock();
        while (true){
            if (ticket > 0) {
                System.out.println("ticket:" + ticket);
                ticket--;
            }
            if (ticket <= 0) {
                break;
            }
        }
        loc.unlock();
    }
}

main:

public class main {
    public static void main(String[] args) {
        threadImp th = new threadImp();

        Thread th1 = new Thread(th);
        Thread th2 = new Thread(th);
        th1.start();
        th2.start();

        for (int i = 0; i < 3; i++) {
            System.out.println("main:" + i);
        }
    }
}

三.等待唤醒机制

1.使用

public class main {
    public static boolean count = false;//有无包子的状态

    public static void main(String[] args) {

        ReentrantLock loc = new ReentrantLock();

        Runnable buy = new Runnable() {
            @Override
            public void run() {
                    while (true){
                        synchronized (loc){
                            System.out.println("消费者");
                            try {
                                loc.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("消费中");
                        }
                    }
            }
        };

        Runnable sell = new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (loc){

                        System.out.println("生产完成");
                        loc.notify();
                    }
                }
            }
        };


        new Thread(sell).start();
        new Thread(buy).start();

    }
}

2.生产者消费者模型

(1)第一版:同一个类

package cn.java.test;


/*
 */

import java.util.concurrent.locks.ReentrantLock;

public class main {
    public static boolean count = false;//有无包子的状态
    static ReentrantLock loc = new ReentrantLock();

    public static void main(String[] args) {

        Runnable buy = new Runnable() {
            @Override
            public void run() {
                    while (true){
                        synchronized (loc){
                            if(count == true){
                                try {
                                    loc.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            System.out.println("正在生产");
                            try {
                                Thread.sleep(5000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            count=true;
                            System.out.println("生产完成");
                            loc.notify();//随机唤醒一个
                        }
                    }
            }
        };

        Runnable sell = new Runnable() {
            @Override
            public void run() {
                while (true){
                    synchronized (loc){
                        if(count == false){
                            try {
                                loc.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        System.out.println("正在吃");
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        count = false;
                        System.out.println("吃完了");
                        loc.notify();
                    }
                }
            }
        };

        new Thread(sell).start();
        new Thread(buy).start();
    }
}

(2)分文件

测试:

public class main {
    public static void main(String[] args) {
        obj a = new obj();
        sellPerson sell = new sellPerson(a);
        buyPerson buy = new buyPerson(a);
        new Thread(sell).start();
        new Thread(buy).start();
    }
}

物品:

public class obj{
    boolean flag=false;
}

生产者:

public class sellPerson implements Runnable{
    private obj temp;

    public sellPerson(obj temp) {
        this.temp = temp;
    }

    @Override
    public void run() {
        while(true) {
            synchronized (temp) {
                if (temp.flag == true) {
                    try {
                        temp.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("正在生产");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                temp.flag = true;
                System.out.println("生产完成");
                temp.notify();//随机唤醒一个
            }
        }
    }
}

消费者:

public class buyPerson implements Runnable {
    private obj temp;

    public buyPerson(obj temp) {
        this.temp = temp;
    }

    @Override
    public void run() {
        while(true){
            synchronized (temp){
                synchronized (temp){
                    if(temp.flag == false){
                        try {
                            temp.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("正在吃");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    temp.flag = false;
                    System.out.println("吃完了");
                    temp.notify();
                }


            }
        }
    }
}

四.线程池使用

public class main {
    public static void main(String[] args) {

        ExecutorService ex = Executors.newFixedThreadPool(3);
        ex.submit(new threadImp());
        ex.submit(new threadImp());
        ex.submit(new threadImp());

        ex.shutdown();//不建议执行,执行完就结束了
    }
}
public class threadImp implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

五.lambda表达式

lambda是java8的一个新特性,格式由三部分组成,省去了面向对象的条条框框

  • 一些参数
  • 一个箭头
  • 一段代码

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑

格式:(参数类型  参数名称)->(代码语句)

():接口中抽象方法的参数列表,没有参数,就空着,有参数就写出参数,多个参数用逗号隔离

->:传递的意思,把参数传递给方法体

{}:重写接口的抽象方法的方法体

lambda的重要参数:

可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。


(1)无参无返回

public interface Cook {
    public abstract void makeCook();
}
public class main {
    public static void main(String[] args) {
        //法1
        fun(new Cook(){
            @Override
            public void makeCook() {
                System.out.println("无lambda");
            }
        });

        //法2
        fun(()->{
            System.out.println("lambda");
        });

    }
    public static void fun(Cook cook){
        cook.makeCook();
    }
}

(2)参数和返回值

public class person {
    private int age;
    private String name;

    public person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class main {
    public static void main(String[] args) {
        person[] arr = {
                new person(18,"张三"),
                new person(19,"李四"),
                new person(17,"王五")
        };
/*
        Arrays.sort(arr, new Comparator<person>() {
            @Override
            public int compare(person o1, person o2) {
                return o1.getAge()-o2.getAge();
            }
        });

        for(person i:arr){
            System.out.println(i.getName()+i.getAge());
        }
*/
        Arrays.sort(arr,(person o1,person o2)->{
            return o1.getAge()-o2.getAge();
        });

        for(person i:arr){
            System.out.println(i.getName()+i.getAge());
        }
    }
}

例2:

public interface Cook {
    public abstract int makeCook(int a,int b);
}
public class main {
    public static void main(String[] args) {
        //调用cal方法,方法的参数是一个接口,可以采用匿名内部类
        cal(2, 3, new Cook() {
            @Override
            public int makeCook(int a, int b) {
                return a+b;
            }
        });
        
        //lambda表达式
        cal(4,5,(int a,int b)->{
            return a+b;
        });
    }

    /*
    定义一个方法:传递两个整数和一个接口
    计算两个整数的和
     */
    public static void cal(int a,int b,Cook cook){
        int c = cook.makeCook(a,b);
        System.out.println(c);
    }
}

(3)参数的省略

可以省略:
1.括号内参数的类型可以省略
2.如果小括号内,有且仅有一个参,小括号可以省略
3.如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略({},return,;)
  注意:要省略,必须三个一起省略
public class main {
    public static void main(String[] args) {
        
        //3.例子
        new Thread(()->{
            System.out.println("3:省略前");
        }).start();
        new Thread(()-> System.out.println("3:省略后")).start();

        // 1 和 3
        person[] arr = {
                new person(18,"张三"),
                new person(19,"李四"),
                new person(17,"王五")
        };

        Arrays.sort(arr,(o1, o2)->o1.getAge()-o2.getAge());

        for(person i:arr){
            System.out.println(i.getName()+i.getAge());
        }
    }
}

注意:

lambda使用方法非常简洁,完全没有面向对象复杂的束缚,但是是羊奶粉的时候必须要注意几点
1.使用lambda必须有抽象方法,而且抽象方法必须有且仅有一个抽象方法
2.使用lambda必须有上下文推断
  即:方法的参数或者局部变量类型必须为Lambda对应的接口类型,才能使用lambda作为给实例的接口
备注:有且仅有一个抽象方法的接口,成为“函数式接口”

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值