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日

相关文章

  • Java读取properties文件连接数据库的方法示例

    下面是详细的攻略过程: 1. 概述 在Java开发中,配置文件是一个很重要的组成部分。其中,properties文件是一种常用的配置文件的形式,用于存储应用程序的配置信息。而在工程中使用到数据库时,我们通常会使用properties文件来存储数据库连接的相关信息。下面就是Java读取properties文件连接数据库的方法示例的完整攻略: 2. 准备工作 首…

    Java 2023年5月20日
    00
  • XML经典问答

    XML经典问答攻略 本文将为您提供针对XML经典问题的攻略,以解决常见的XML相关问题。以下是您需要注意的几个方面: 1. XML文档结构 XML文件通常由一个根元素(root element)组成,并由开始标签和结束标签加以表示。中间可以嵌套若干子元素。元素可以包含属性(attribute)或文本(text)。如下所示: <?xml version=…

    Java 2023年5月20日
    00
  • 关于Java中对象的向上转型和向下转型

    什么是多态? 同一个类调用同一个方法会产生不同的影响/结果 这就是多态 public class Pet{ public void eat(){ System.out.println(“Pet eat…”) } } class Dog extends Pet{ public void eat(){ System.out.pringln(“Dog eat.…

    Java 2023年4月22日
    00
  • java 两个数组合并的几种方法

    Java两个数组合并的几种方法 介绍 在Java中,有时候需要将两个数组合并成一个数组。本文将介绍Java中合并两个数组的几种方法。 方法一:使用for循环 首先,我们可以使用for循环来合并两个数组。具体的操作是,将第一个数组的元素复制到新的数组中,然后将第二个数组的元素复制到新的数组中。 示例代码: public static int[] mergeAr…

    Java 2023年5月27日
    00
  • JSP中的include有几种形式?都有什么区别?

    JSP中的include有两种形式:静态include和动态include。 静态include 静态include是在页面编译时就将包含的文件内容插入到该位置,因此适用于内容不频繁变化的页面。静态include的语法如下: <%@ include file="included.jsp" %> 其中,included.jsp是…

    Java 2023年6月15日
    00
  • JAVA加密算法实密钥一致协议代码示例

    让我先解释一下题目的含义。所谓“JAVA加密算法实密钥一致协议代码示例”,是指使用Java编程语言实现加密算法中的“密钥一致协议”(Key Agreement)的代码示例。这个协议的目的是让双方在不泄露密钥的情况下完成一次会话的加密和解密。 实现这个协议可以使用Java中的JCE(Java Cryptography Extension)库。下面是一份简单的实…

    Java 2023年5月27日
    00
  • Java使用POI实现导出Excel的方法详解

    首先我们来讲解一下Java使用POI实现导出Excel的方法详解。 一、POI介绍 Apache POI是Apache软件基金会的开源项目,是用于Java编程语言处理Microsoft Office格式文件的开源库。POI提供API给用户对Excel、Word和PowerPoint等文件进行读和写的功能。POI提供了对Excel 97-2003及Excel …

    Java 2023年5月26日
    00
  • Java C++ 算法leetcode828统计子串中唯一字符乘法原理

    Java C++ 算法leetcode828统计子串中唯一字符乘法原理 题目描述 给定一个字符串,你需要统计其中唯一字符的个数。 具体地,你需要统计所有的出现恰好一次的字符的个数。 示例 输入: “ABCDEF”输出: 6解释: 出现一次的字符有 ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’,因此唯一字符的个数为 6。 输入: “ABCDEFAB…

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