彻底搞懂Java多线程(一)

彻底搞懂Java多线程(一)

为什么需要多线程

在Java应用程序中,多线程可以帮助我们利用CPU资源,提高程序的执行效率,加速程序的运行速度。理论上,一个程序的执行速度可以比单线程的程序快1到100倍不等。

Java多线程的实现方式

Java多线程的实现方式主要有两种:继承Thread类和实现Runnable接口。

继承Thread类

使用继承Thread类的方式,需要重写Thread类的run()方法,并在该方法中实现多线程的操作。

public class MyThread extends Thread {
    // 重写run方法
    public void run() {
        // 多线程的操作
    }
}

实现Runnable接口

使用实现Runnable接口的方式,需要在类中实现Runnable接口的run()方法,并在该方法中实现多线程的操作。然后,创建Thread类的实例,将Runnable对象作为它的构造函数参数传递,最后调用start()方法启动线程。

public class MyRunnable implements Runnable {
    // 实现run方法
    public void run() {
        // 多线程的操作
    }
}

public class Test {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

Java多线程的生命周期

Java多线程的生命周期包括5个状态:新建、就绪、运行、阻塞和死亡。

新建状态

当用new关键字创建一个Thread对象时,线程进入新建状态。

就绪状态

当线程调用start()方法时,线程进入就绪状态,等待JVM调度执行。

运行状态

当线程被JVM调度执行时,线程进入运行状态。

阻塞状态

当线程在等待一个监视器锁或某些操作执行的结果时,线程进入阻塞状态。

死亡状态

当线程执行完run()方法后或因异常而结束时,线程进入死亡状态。

Java多线程的同步机制

在Java多线程环境中,同步机制是用来解决多个线程访问共享资源的问题。

synchronized关键字

synchronized关键字可以用来确保同一时间只有一个线程能够访问共享资源。

public class Test {
    // 定义共享变量count
    private static int count = 0;
    // 在方法中使用synchronized关键字同步访问count变量
    public synchronized static void add() {
        count++;
    }
    public static void main(String[] args) throws InterruptedException {
        // 创建20个线程
        for (int i = 0; i < 20; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    // 每个线程循环调用1000次add方法
                    for (int i = 0; i < 1000; i++) {
                        add();
                    }
                }
            });
            thread.start();
        }
        // 等待所有线程执行完毕
        Thread.sleep(1000);
        System.out.println(count);
    }
}

wait()和notify()方法

wait()和notify()方法是Java中用于线程同步的另外两个重要的方法。

  • wait()方法会让当前的线程进入等待状态,直到其它线程调用notify()方法将其唤醒。
  • notify()方法会唤醒处于等待状态的线程,但不会释放锁,因此必须等到执行notify()方法的线程释放锁之后其他线程才能继续执行。
public class Test {
    public static void main(String[] args) throws InterruptedException {
        final Object lock = new Object();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    try {
                        System.out.println("Thread1等待...");
                        lock.wait();
                        System.out.println("Thread1被唤醒!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    try {
                        System.out.println("Thread2睡眠1秒钟...");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.notify();
                }
            }
        });
        thread1.start();
        thread2.start();
    }
}

示例说明

示例1

这是一个简单的多线程示例,创建了20个线程,每个线程循环调用1000次add方法,将一个静态变量count的值加1。

public class Test {
    // 定义共享变量count
    private static int count = 0;
    // 在方法中使用synchronized关键字同步访问count变量
    public synchronized static void add() {
        count++;
    }
    public static void main(String[] args) throws InterruptedException {
        // 创建20个线程
        for (int i = 0; i < 20; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    // 每个线程循环调用1000次add方法
                    for (int i = 0; i < 1000; i++) {
                        add();
                    }
                }
            });
            thread.start();
        }
        // 等待所有线程执行完毕
        Thread.sleep(1000);
        System.out.println(count);
    }
}

示例2

这个示例展示了wait()和notify()方法的使用。在线程1调用lock.wait()方法进入等待状态后,线程2睡眠1秒钟,然后调用lock.notify()方法唤醒在线程1中等待的线程。

public class Test {
    public static void main(String[] args) throws InterruptedException {
        final Object lock = new Object();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    try {
                        System.out.println("Thread1等待...");
                        lock.wait();
                        System.out.println("Thread1被唤醒!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    try {
                        System.out.println("Thread2睡眠1秒钟...");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.notify();
                }
            }
        });
        thread1.start();
        thread2.start();
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:彻底搞懂Java多线程(一) - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java并发编程之死锁相关知识整理

    Java并发编程之死锁相关知识整理 什么是死锁? 死锁是指两个或多个线程在执行过程中,因互相竞争资源而造成的一种互相等待的现象,若无外力干涉势将无法推进下去。 什么情况下会发生死锁? 当系统资源不足时,进程会因争夺资源而陷入僵局。若此时系统能够协调资源分配,以便令进程有序地进行,便可避免进程间死锁的发生。 在Java并发编程中,一般出现死锁的情况是因为线程之…

    多线程 2023年5月16日
    00
  • php session的锁和并发

    让我们来详细讲解下面的问题:“php session的锁和并发”: 什么是php session? PHP Session是一个Web开发中常用的会话机制,用于在服务器和浏览器之间跟踪用户。 在会话期间,可以将所有与该用户相关的信息存储在其会话中,而不必在每次请求时都需要重复登录和授权。 PHP Session的锁机制 PHP Session采用了文件锁机制…

    多线程 2023年5月16日
    00
  • 深入解析Java并发程序中线程的同步与线程锁的使用

    深入解析Java并发程序中线程的同步与线程锁的使用 在Java并发程序中,线程的同步和线程锁是必不可少的。线程的同步是指多个线程协同工作,按一定的顺序执行,而线程锁则是保证多个线程访问共享资源时数据的正确性和一致性。 线程同步 Java中线程同步的主要方式有以下两种: 1. synchronized关键字 synchronized关键字可以修饰方法和代码块,…

    多线程 2023年5月16日
    00
  • 并发编程之Java内存模型

    关于“并发编程之Java内存模型”这一话题,我将给您详细的讲解,包括以下内容: 什么是Java内存模型 Java内存模型中的内存间交互操作 如何保证内存可见性 如何保证原子性 如何保证顺序性 示例说明 总结 1. 什么是Java内存模型 Java内存模型(Java Memory Model,简称JMM)是Java虚拟机在并发编程中对内存进行抽象化的一种规范,…

    多线程 2023年5月17日
    00
  • redis 解决库存并发问题实现数量控制

    请允许我详细讲解一下“redis 解决库存并发问题实现数量控制”的完整攻略。 简介 在电商、餐饮等各个领域,都会遇到商品库存有限的情况,当多个用户同时对同一件商品进行下单或者支付时,就会出现库存并发问题。解决这个问题的方案之一就是使用 Redis,通过 Redis 的原子性的操作来实现库存的控制。 具体步骤 下面是使用 Redis 实现库存控制的具体步骤: …

    多线程 2023年5月16日
    00
  • Java并发编程之Executor接口的使用

    Java并发编程之Executor接口的使用 Java中的线程池在实现多线程编程中有着重要的作用。在Java中,线程池的实现需要通过java.util.concurrent.Executor接口来实现。在本文中,我们将讲解Executor接口的用法,以及如何使用线程池来提高并发效率。 什么是Executor接口? Executor接口是Java线程池的核心接…

    多线程 2023年5月17日
    00
  • java基于C/S结构实现多线程聊天室

    Java基于C/S结构实现多线程聊天室的攻略如下: 确定需求和功能点 首先需要明确聊天室的功能,如聊天、发送文件、创建和加入房间等。然后确定需要实现的功能点,例如登录验证、用户管理、消息广播等。 选择合适的框架和技术 选择适合的框架和技术可以提高开发效率和应用性能。Java中可以选择基于Socket和ServerSocket类实现TCP连接,或者使用Nett…

    多线程 2023年5月16日
    00
  • Redis高并发问题的解决方法

    Redis高并发问题的解决方法 1. Redis是什么 Redis是一个高性能的内存数据结构存储系统,常用于缓存、分布式锁、消息队列、计数器等场景,因为其迅速的读写速度和多种数据结构的支持而受到广泛的喜爱。 2. Redis高并发问题分析 Redis在进行并发访问时,会存在以下几个问题: 线程安全问题:Redis单线程模型无法支持并发访问,需要使用线程安全的…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部