栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

九、线程学习

Java 更新时间:发布时间: 百科书网 趣学号
进程和线程


线程创建 继承Thread类(重写run方法)

调用start方法执行
总结注意:线程开启不一定立即执行,由CPU调度执行

主线程和另一个线程交替执行

实现Runnale接口

实现Callable接口(了解即可)
public class TestCallable implements Callable {
    private String url;
    private String name;
    public TestCallable(String url,String name){
        this.url = url;
        this.name = name;
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable t1 = new TestCallable("https://profile.csdnimg.cn/0/0/E/1_m0_61453929","1.jpg");
        TestCallable t2 = new TestCallable("https://img-blog.csdnimg.cn/20190927151026427.png?x-oss-process=image/resize,m_fixed,h_64,w_64","2.jpg");
        TestCallable t3 = new TestCallable("https://img-blog.csdnimg.cn/20190918135101160.png?x-oss-process=image/resize,m_fixed,h_64,w_64","3.jpg");
        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(3);
        //提交执行
        Future r1 = ser.submit(t1);
        Future r2 = ser.submit(t2);
        Future r3 = ser.submit(t3);
        //获取结果
        Boolean rs1 = r1.get();
        Boolean rs2 = r2.get();
        Boolean rs3 = r3.get();
        //关闭服务
        ser.shutdown();
    }
    @Override
    public Boolean call() {
        WebDownLoader webDownLoader = new WebDownLoader();
        webDownLoader.downLoader(url,name);
        System.out.println("下载了文件名:" + name);
        return null;
    }
}
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方法出现异常");
        }
    }
}

callable的好处:

  1. 可以定义返回值
  2. 可以抛出异常
静态代理
public class StaticProxy {
    public static void main(String[] args) {
        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.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 after(){
        System.out.println("结婚后,收尾款");
    }
    private void before(){
        System.out.println("结婚前,布置现场");
    }
}
静态代理模式总结:

1.真实对象和代理对象都要实现同一个接口
2.代理对象要代理真实的角色

好处:

1.代理对象可以做很多真实对象做不了的事情
2.真实对象专注做自己的事情

Lamda表达式 函数式接口(只有一个抽象方法)

总结

1.lamdba表达式只能由一行代码的情况下才能简化为一行。如果由多行,那么就用代码块包裹
2.前提是接口为函数式接口
3.多个参数也可以去掉参数类型,要去掉都去掉,必须加上括号

线程状态 线程状态图


线程方法

线程休眠【sleep】

可以模拟网络延迟、倒计时、显示当前时间

模拟网络延迟

倒计时

打印当前时间

线程礼让【yield】

线程插队【join】

守护线程【daemon】

线程分为用户线程和守护线程
虚拟机必须确保用户线程执行完毕
虚拟机不用等待线程执行完毕
如:后台记录操作日志、监控内存、垃圾回收等

线程优先级

线程同步

同步方法

同步方法默认锁定的是this,当前这个类

同步块
public class UnsafeBank {
    public static void main(String[] args) {
        //账户
        Account account = new Account(100, "结婚基金");
        Drawing you = new Drawing(account, 50, "你");
        Drawing girlFriend = new Drawing(account, 100, "girlFriend");
        you.start();
        girlFriend.start();
    }
}

class Account{
    int money;//余额
    String name;//卡名

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}
//银行模拟取款
class Drawing extends Thread{
    Account account;//账户
    int drawingMoney;//取了多少钱
    int nowMoney;//现在多少钱
    public Drawing(Account account,int drawingMoney,String name){
        super(name);
        this.account =account;
        this.drawingMoney = drawingMoney;

    }

    //synchronized 同步方法 默认锁的是this
    @Override
    public void run() {
        //锁的对象是变化的量,保证安全
        synchronized (account){
            //判断有没有钱
            if(account.money- drawingMoney < 0){
                System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
                return;
            }
            //sleep可以放大问题的发生性
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //卡内余额 = 余额 - 你取的钱
            account.money = account.money - drawingMoney;
            //你手的钱
            nowMoney = nowMoney + drawingMoney;
            System.out.println(account.name + "余额为"+account.money);
            //Thread.currentThread().getName() 等价于 this.getName()
            System.out.println(this.getName() + "手里的钱" + nowMoney);
        }

    }
}


死锁 死锁产生的条件

Lock


ReentrantLock lock = new ReentrantLock(); 可重用锁

synchronized 和 Lock 的区别

线程通信【生产者和消费者】

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/959775.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号