Java多线程实例

Java多线程实例攻略

Java多线程是Java的一大特性,它可以使程序在运行时同时执行多个任务,提高了程序的效率。在本篇文章中,我们将讲述Java多线程的实例及使用方法,包含以下主题:

  1. Java多线程基本概念
  2. Java多线程创建方式
  3. Java多线程共享变量及协调执行
  4. 多线程应用——生产者和消费者模型

1. Java多线程基本概念

在Java中,一个程序可以有多个线程同时执行,每个线程都是独立的,有自己的栈空间和程序计数器,但是它们共享进程的内存空间。

Java多线程可以分为用户线程和守护线程两种类型。一般情况下,用户线程不会随着程序的结束而结束,而守护线程则会随着程序的结束而结束。

2. Java多线程创建方式

Java多线程可以通过两种方式创建,一种是继承Thread类,一种是使用Runnable接口。Thread类和Runnable接口都提供了run()方法用于定义线程要执行的任务。

示例一:通过继承Thread类创建线程

public class MyThread extends Thread {
    public void run() {
        System.out.println("Hello World!");
    }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

示例二:通过实现Runnable接口创建线程

public class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Hello World!");
    }

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

3. Java多线程共享变量及协调执行

在多线程程序中,可能会出现多个线程同时访问同一个变量的情况,为了避免出现数据竞争等问题,我们需要采取相应的措施。

Java提供了synchronized关键字用于实现线程同步,synchronized可以用来修饰方法和代码块,确保同一时间只有一个线程可以访问这段代码。

同时,Java还提供了wait()、notify()和notifyAll()方法实现线程间的协作。wait()方法可以使线程等待某个条件满足的通知,而notify()和notifyAll()方法可以用于唤醒等待线程。

示例三:通过synchronized关键字实现线程同步

public class SynchronizedDemo {
    private int count = 0;

    public synchronized void add() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }

    public static void main(String[] args) {
        SynchronizedDemo synchronizedDemo = new SynchronizedDemo();

        for (int i = 0; i < 1000; i++) {
            new Thread(() -> synchronizedDemo.add()).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(synchronizedDemo.getCount()); // 打印1000
    }
}

示例四:通过wait()和notify()方法实现线程间协作

public class WaitNotifyDemo {
    private static boolean flag = false;
    private static Object lock = new Object();

    public static void main(String[] args) {
        Thread waitThread = new Thread(new WaitTask(), "WaitThread");
        Thread notifyThread = new Thread(new NotifyTask(), "NotifyThread");

        waitThread.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        notifyThread.start();
    }

    static class WaitTask implements Runnable {
        public void run() {
            synchronized (lock) {
                while (!flag) {
                    System.out.println(Thread.currentThread() + " begin waiting!");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread() + " finish waiting!");
            }
        }
    }

    static class NotifyTask implements Runnable {
        public void run() {
            synchronized (lock) {
                flag = true;
                lock.notifyAll();
                System.out.println(Thread.currentThread() + " notify all!");
            }
        }
    }
}

4. 多线程应用——生产者和消费者模型

生产者和消费者模型是常见的多线程应用场景之一,它通常用于解决生产和消费的速度不匹配的问题。

在生产者和消费者模型中,通常会有一些共享的数据结构,例如队列,生产者会向队列中添加数据,而消费者会从队列中获取数据并消耗掉。当队列中没有数据时,消费者线程会进入等待状态,当队列中有数据时,生产者线程会通知消费者线程来消费。

示例五:生产者和消费者模型的实现

public class ProducerConsumerDemo {
    private Queue<Integer> queue = new LinkedList<>();
    private int maxSize = 10;

    public void produce() {
        while (true) {
            synchronized (queue) {
                while (queue.size() == maxSize) { // 队列已经满了
                    try {
                        System.out.println("Queue is full, Producer thread waiting for consumer to consume...");
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                Random random = new Random();
                int num = random.nextInt(100);
                System.out.println("Producing: " + num);
                queue.add(num);
                queue.notifyAll();
            }
        }
    }

    public void consume() {
        while (true) {
            synchronized (queue) {
                while (queue.isEmpty()) { // 队列为空
                    try {
                        System.out.println("Queue is empty, Consumer thread waiting for producer to produce...");
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                int num = queue.poll();
                System.out.println("Consuming: " + num);
                queue.notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        ProducerConsumerDemo demo = new ProducerConsumerDemo();
        new Thread(() -> demo.produce()).start();
        new Thread(() -> demo.consume()).start();
    }
}

以上是Java多线程实例的完整攻略,希望能对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程实例 - Python技术站

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

相关文章

  • JavaWeb实现学生管理系统的超详细过程

    JavaWeb实现学生管理系统的超详细过程 本文将着重对如何使用JavaWeb技术实现一个基本的学生管理系统进行详细讲解。本文将分别介绍系统需求分析、数据库设计、项目创建、前端页面设计、后端代码编写及测试等方面的知识点。 系统需求分析 首先,我们需要明确我们要实现的系统应该具备哪些功能。在本文的学生管理系统中,我们需要实现以下功能: 实现学生的增加、删除、修…

    Java 2023年5月20日
    00
  • Java 数据库连接池 Tomcat介绍

    下面开始对“Java 数据库连接池 Tomcat介绍”的攻略进行详细讲解。 一、什么是数据库连接池 在应用中,每次向数据库请求都会建立一个与数据库的连接。但是频繁地打开和关闭连接会给数据库服务器带来额外的负荷,造成系统性能下降。而使用连接池技术,可以在应用启动时就预先创建一组数据库连接,放入连接池中。当需要使用数据库连接时,就从连接池中取出一个连接,使用完后…

    Java 2023年6月2日
    00
  • Spring Data JPA实现排序与分页查询超详细流程讲解

    下面就是关于“Spring Data JPA实现排序与分页查询超详细流程讲解”的完整攻略,包含以下内容: 步骤一:导入必要的依赖和配置 首先需要确保在你的项目中已经导入了Spring Data JPA相关依赖,包括spring-data-jpa、hibernate-core、mysql-connector-java等。在pom.xml中添加以下依赖: &lt…

    Java 2023年5月20日
    00
  • Java Apache Commons报错“SQLException”的原因与解决方法

    “SQLException”是Java中处理数据库操作时常见的异常,通常由以下原因之一引起: 数据库连接错误:如果数据库连接失败,则可能会出现此错误。在这种情况下,需要检查数据库连接以解决此问题。 SQL语句错误:如果SQL语句错误,则可能会出现此错误。在这种情况下,需要检查SQL语句以解决此问题。 以下是两个实例: 例1 如果数据库连接失败,则可以尝试检查…

    Java 2023年5月5日
    00
  • Java线程重复执行以及操作共享变量的代码示例

    Java线程是一种轻量级进程,可以同时执行多个线程,实现并发操作。有时候我们需要让线程重复执行某个任务,并且需要注意操作共享变量的线程安全问题。下面就是以代码示例的形式,详细讲解“Java线程重复执行以及操作共享变量”的完整攻略。 线程重复执行 线程重复执行的方式有多种,其中最常见的方式是使用循环语句,如while循环、for循环等。下面以while循环和延…

    Java 2023年5月18日
    00
  • java jdbc连接和使用详细介绍

    Java JDBC连接和使用详细介绍 什么是JDBC? JDBC(Java Database Connectivity)是Java语言操作数据库的统一接口,它为访问不同的数据库提供了一个标准的类库。使用JDBC可以实现Java和数据库的交互操作。 JDBC步骤 使用JDBC进行数据库操作主要包括以下步骤: 加载JDBC驱动程序 建立数据库连接 创建Prepa…

    Java 2023年5月23日
    00
  • Spring Boot中使用Spring MVC的示例解析

    Spring Boot中使用Spring MVC的示例解析 在开始使用Spring MVC之前,我们需要先安装并配置好Spring Boot和Spring MVC。安装时我们可以使用Spring官方提供的脚手架工具spring initilizr,也可以直接在IDE中创建Spring Boot项目并选择其中包含Spring MVC的依赖。 安装完毕之后,我们…

    Java 2023年6月15日
    00
  • Tomcat Catalina为什么不new出来原理解析

    下面我会详细讲解“Tomcat Catalina为什么不new出来原理解析”的完整攻略。 背景 Tomcat Catalina是 Apache Tomcat 服务器的核心组件。关于为什么 Tomcat Catalina 不直接 new 出来,在 Tomcat 的官方文档中并没有详细的解释,本文将尝试解析该问题。 解析 在 Tomcat 的启动过程中,Cata…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部