8、多线程

本文详细介绍了Java中的线程与进程概念,包括进程的查看、线程的创建与生命周期,以及线程的串行与并发执行。还讨论了线程休眠、线程池的使用、同步机制、wait和sleep的区别,以及线程安全问题。通过实例代码展示了如何在Java中实现和管理线程,帮助读者深入理解Java多线程编程。
摘要由CSDN通过智能技术生成


Java零基础极速入门-讲师:海波

失败,是正因你在距成功一步之遥的时候停住了脚步。


1、线程中的进程

// 用户的程序就是一个进程,正在运行的程序,不是正在执行的程序,抢到cpu的执行全才是正在执行的程序。
// 进程的名字就是执行的类的名字

查看java中的进程

C:\Users\85411>jps
567920
593984 Jps
570212 RemoteMavenServer36
592084 Launcher

2、进程中的线程

public class Demo {
    public static void main(String[] args) {
        // 线程
        // currentThread()获取当前运行的线程
        Thread thread = Thread.currentThread();
        // getName() 用于获取线程的名字
        System.out.println(thread.getName());
        // main方法运行在main线程中
        
        // 1.Java程序在运行的时候默认就会产生一个进程
        // 2.这个进程会有一个主线程
        // 3.代码都在主线程中执行
    }
}

3、自己的第一个线程

public class Demo {
    public static void main(String[] args) {
        // 线程
        // currentThread()获取当前运行的线程
        Thread thread = Thread.currentThread();
        // getName() 用于获取线程的名字
        System.out.println(thread.getName());

        // 创建线程
        MyThread t = new MyThread();
        // 启动线程
        t.start();
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("Thread:"+Thread.currentThread().getName());
    }
}

4、线程的生命周期

在这里插入图片描述

/**
 *  NEW :新建
 *  RUNNABLE :可运行
 *  BLOCKED :阻塞
 *  WAITING :等待
 *  TIMED_WAITING :定时等待
 *  TERMINATED :终止
 */

5、线程执行方式(串行和并发)

5.1、串行执行

多个线程连接成串,然后按照顺序执行。

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

        // 创建线程
        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2();
        t1.start();
        t2.start();
        // join()当前线程执行完,在执行其他线程。
        t1.join();
        t2.join();
        
        // currentThread()获取当前运行的线程
        Thread thread = Thread.currentThread();
        // getName() 用于获取线程的名字
        System.out.println(thread.getName());
    }
}
class MyThread1 extends Thread{
    @Override
    public void run() {
        System.out.println("Thread1:"+Thread.currentThread().getName());
    }
}
class MyThread2 extends Thread{
    @Override
    public void run() {
        System.out.println("Thread2:"+Thread.currentThread().getName());
    }
}

5.2、并发

多个线程是独立,谁抢到CPU的执行权,谁就能执行。

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

        // 创建线程
        MyThread1 t1 = new MyThread1();
        MyThread2 t2 = new MyThread2();
        t1.start();
        t2.start();

        // currentThread()获取当前运行的线程
        Thread thread = Thread.currentThread();
        // getName() 用于获取线程的名字
        System.out.println(thread.getName());
    }
}
class MyThread1 extends Thread{
    @Override
    public void run() {
        System.out.println("Thread1:"+Thread.currentThread().getName());
    }
}
class MyThread2 extends Thread{
    @Override
    public void run() {
        System.out.println("Thread2:"+Thread.currentThread().getName());
    }
}

6、线程休眠

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

        // 休眠1秒中,打印一次字符串
        while (true) {
            Thread.sleep(1000);
            System.out.println("main线程执行完毕");
        }
    }
}

7、工作

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

        // 启动方式一
        MyThread1 thread1 = new MyThread1("1");
        thread1.start();
        // 启动方式二
        MyThread2 thread2 = new MyThread2("2");
        Thread thread = new Thread(thread2);
        thread.start();
        // main线程
        System.out.println("main线程运行结束");

    }
}
// 实现线程方式一
class MyThread1 extends Thread{
    private String name;

    public MyThread1(String name){
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println(name+"线程运行结束");
    }
}
// 实现线程方式二
class MyThread2 implements Runnable{
    private String name;

    public MyThread2 (String name){
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println(name + "线程运行结束");
    }
}

8、线程池

在这里插入图片描述

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

        // 线程池:现成的容器
        // 线程池会根据需要,在启动时,创建一个或多个线程对象
        // Java中有4种比较常见的线程池
        // 1.创建固定数量的线程对象
        //ExecutorService executorService = Executors.newFixedThreadPool(3);
        // 2.根据需求动态创建线程
        //ExecutorService executorService = Executors.newCachedThreadPool();
        // 3.单一线程
        //ExecutorService executorService = Executors.newSingleThreadExecutor();
        // 4.定时调度线程
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);

        // 开启线程数量
        for (int i = 0; i < 5; i++) {
            executorService.submit(new MyThread2());
        }

    }
}
class MyThread2 implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "线程运行结束");
    }
}

9、同步

public class Demo {
    public static void main(String[] args){
        // 多线程访问同步方法时,只能一个一个访问,同步操作
        // new Hashtable<>();
        // synchronized关键字还可以修饰代码块,称之为同步代码块
        /*
                synchronized (用于同步对象){
                    处理逻辑
                }
         */
        Num num = new Num();
        User user = new User(num);
        user.start();
        Bank bank = new Bank(num);
        bank.start();
    }
}
class Num{

}
class Bank extends Thread{
    private Num num;
    public Bank(Num num){
        this.num = num;
    }

    @Override
    public void run() {
        synchronized (num){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("9:00,开始营业,开始叫号");
            num.notifyAll();//唤醒所有等待

        }
    }
}
class User extends Thread{
    private Num num;
    public User(Num num){
        this.num = num;
    }

    @Override
    public void run() {
        synchronized (num){
            System.out.println("我是号码1,银行还没开门,我需要等一会");
            try {
                num.wait();//等待
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("叫到我的号了,该我办业务了");
        }
    }
}

10、wait和sleep

public class Demo {
    public static void main(String[] args){
        // 阻塞
        // 1.名字
        //  wait:等待
        //  sleep:休眠
        // 2.从属关系
        //  wait:Object 成员方法
        //  sleep:Thread 静态方法
        // 3.使用方式
        //  wait:只能使用在同步代码中
        //  sleep:可以在任意地方使用
        // 4.阻塞时间
        //  wait:超时时间(会发生错误)
        //  sleep:休眠时间(不会发生错误)
        // 5.同步处理
        //  wait:执行wait方法,其他线程有机会执行当前的同步操作
        //  sleep:执行sleep方法,其他线程没有机会执行当前的同步操作
    }
}

11、线程安全问题

public class Demo {
    public static void main(String[] args){
        // 线程安全问题
        // 多个线程在并发执行时,修改了共享内存中共享对象的属性,导致的数据冲突问题
        
        User user = new User(); //User是两个线程的共享对象,user.name是共享属性

        Thread t1 = new Thread(() ->{
            user.name = "zhangsan"; //对共享属性的修改
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(user.name);
        });
        Thread t2 = new Thread(() ->{
            user.name = "lisi"; //对共享属性的修改
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(user.name);
        });
        
        t1.start(); // 将共享属性修改为zhangsan,休眠1秒
        t2.start(); // 将共享属性修改为lisi,休眠1秒,这时两个线程打印共享内存中的数据,都是lisi
        
        System.out.println("main线程"); // main不休眠,先执行完毕
    }
}
class User{
    String name;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值