浏览器标题切换
浏览器标题切换end

Day62:java-多线程

 概念:程序、进程、线程

线程:是一个程序内部的一条执行路径(如果把进程比作河,那么线程就相当于河流的分支)
cpu的核数:几核的cpu代表一个瞬时时间能处理任务数
主频:任务之间的切换速度
核数越多、主频越快越好

 

多线程的创建和使用

多线程:一个进程(一个程序运行时),可以分化为并行执行多个线程(多个子程序)

何时需要多线程?
1、程序需要同时执行两个或者多个任务
2、需要一些后台运行的程序多线程的创建和启动,通过java.lang.Threat实现
Thread类特性:
run():每个线程通过某个特定的Thread对象的run()方法(它的主体叫做线程体,想要运行的代码逻辑写在这个方法里)来完成操作
start():通过该Thread对象的start()方法(启动线程)来调用这个线程

创建线程:
方法一:继承Thread类实现多线程

CC.java
复制代码
package jicheng;

import java.lang.*;

public class CC extends Thread {

    @Override
    public void run() {
        System.out.println("这里写的是多线程运行的代码");
        for (int i = 1; i <= 8; i++)
            System.out.println(i);
    }
}
复制代码

B.java
复制代码
package jicheng;

import java.lang.*;

public class B {
    public static void main(String[] args) {
        //new实例的时候用其父类去接受即可(对象的多态)
        Thread t0 = new CC();  //继承Threat类的线程
        t0.start();//启动线程,运行run方法
//        start执行好之后的main()方法的其他的代码与run方法的代码并行
        System.out.println("*****");
        //发现每次运行的结果不一样
        // 输出的和run方法输出混合,且顺序不一定,但是保持自己的输出顺序
        //这个就是多线程的异步,同步:代码严格按照从上到下执行
        //异步:开启线程之后run方法运行的和主程序的代码是并行执行的,没有先后关系
    }
}
复制代码

 

方法二:实现Runnable接口实现多线程
CC.java
复制代码
package jicheng;

import java.lang.*;

public class CC implements Runnable{//通过实现Runnable接口方式实现多线程

    @Override
    public void run() {
        System.out.println("这里写的是Runnable多线程运行的代码");
        for (int i = 1; i <= 8; i++)
            System.out.println(i);
    }
}
复制代码


B.java
复制代码
package jicheng;

import java.lang.*;

public class B {
    public static void main(String[] args) {
        Thread t1 = new Thread(new CC());//传入Runnable实例
        t1.start();
        //或者可以这样写,多个线程可以这样子写
        // Thread t2 = new Thread(new CC(), "线程的名称");
    }
}
复制代码

 

两种方法实现多线程的总结:

  • 接口:接口的方法都没有方法体,叫做实现run方法(一般用这个)

  • 继承:叫做重写run方法


实现方法的好处:

  1. 避免单继承的局限性;(因为继承的话,如果父类是Thread就不能是其他的了,实现接口不影响去继承其他父类)

  2. 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

多线程的优点:

  1. 提高应用程序的相应。对图形化界面更有意义,增强用户体验;

  2. 提高应用程序的CPU利用率;

  3. 改善程序结构(将长和复杂的进程分为多个线程,独立运行,利于理解和修改)。

 

线程的生命周期

 

 

线程的同步与死锁

一个用户有3000元,需要实现支付宝和微信同时取出2000元

复制代码
package jicheng;

import java.lang.*;

public class B {
    public static void main(String[] args) {
        Acount a = new Acount();//定义账户对象

        //多线程对象
        User u_w = new User(a, 2000);//分别取出2000
        User u_z = new User(a, 2000);

        //微信和支付宝的线程
        Thread wechat = new Thread(u_w, "微信");//多线程对象和名称
        Thread pay = new Thread(u_z, "支付宝");

        wechat.start();
        pay.start();

    }
}
//多线程出现安全问题:
//多线程调用这个方法会发现:线程共享资源的时候,一个线程在执行这个方法没有完毕时,另一个线程开始执行这个方法
//出现问题:钱变成负数
//解决:对于共享数据的操作,让一个线程执行完再让其他线程参与
//通过synchronized同步锁来完成,在方法上加上该关键字即可
//在普通方法上加同步锁,锁的是整个对象
class Acount {
    public static int money = 3000;//账户原有3000元,全局变量

    public synchronized void drawing(int m) {
        String name = Thread.currentThread().getName();
        if (money < m) {
            System.out.println(name + "  余额不足");
        } else {
            System.out.println(name + "  原来:" + money);
            System.out.println(name + "  取走:" + m);
            money -= m;
            System.out.println(name + "  余额:" + money);
        }
    }
}

class User implements Runnable {
    Acount acount;
    int money;

    public User(Acount acount, int money) {
        this.acount = acount;
        this.money = money;
    }

    @Override
    public void run() {
        acount.drawing(money);
    }
}
View Code
复制代码

代码的注释看一下。

 

在这个代码中,可以明白同步锁的作用,

同步锁关键字:synchronized。

这个代码不关键字,则:

多线程出现安全问题:

多线程调用drawing(取出钱)这个方法会发现:线程共享资源的时候,一个线程在执行这个方法没有完毕时,另一个线程开始执行这个方法

出现问题:钱变成负数。

解决:对于共享数据的操作,让一个线程执行完再让其他线程参与。

通过synchronized同步锁来完成,在方法上加上该关键字即可。

注意:在普通方法上加同步锁,锁的是整个对象,不是某一个方法,不同的对象就是不同的锁;静态的方法加synchronized,对于所有的对象都是同一个锁。

除了上面代码内容,

同步锁还可以这样写:

synchronized(对象){
  //需要被同步的代码
}

如果针对对象要加同步锁,就加在方法上;

针对某一段代码需要加同步锁,就在代码块上加上同步锁。

 

不加同步锁关键字输出:

 

 

加了同步锁关键字输出:

 

 

 

 

 

线程的通信

这三个方法只能用在有同步锁的方法或者代码块上

 

 



 

posted @   抓水母的派大星  阅读(157)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示