首页 > 编程语言 >Java中的多线程详解

Java中的多线程详解

时间:2024-07-13 15:20:02浏览次数:7  
标签:Java Thread void example 详解 线程 new 多线程 public

Java中的多线程详解

大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!

多线程编程是Java开发中一个非常重要的主题。在多线程环境下,程序可以同时执行多个任务,从而提高程序的执行效率。本文将详细介绍Java中的多线程,包括线程的创建、线程的生命周期、线程的同步、线程间的通信以及常见的线程安全问题。

一、线程的创建

在Java中,创建线程有两种主要方式:继承Thread类和实现Runnable接口。

  1. 继承Thread
package cn.juwatech.threads;

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread is running.");
    }

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

在这个示例中,我们通过继承Thread类创建了一个新的线程,并重写了run方法。

  1. 实现Runnable接口
package cn.juwatech.threads;

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Thread is running.");
    }

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

在这个示例中,我们通过实现Runnable接口创建了一个新的线程,并将Runnable对象传递给Thread对象。

二、线程的生命周期

一个线程在其生命周期中会经历以下几个状态:

  1. 新建(New):线程对象被创建,但尚未调用start方法。
  2. 就绪(Runnable):线程对象调用了start方法,线程进入就绪状态,等待CPU调度执行。
  3. 运行(Running):线程获得CPU时间片,开始执行run方法的代码。
  4. 阻塞(Blocked):线程因某种原因放弃CPU使用权,进入等待状态,直到满足条件重新进入就绪状态。
  5. 终止(Terminated):线程执行完run方法,或因异常退出,线程生命周期结束。

三、线程的同步

在多线程环境中,多个线程可能会同时访问共享资源,导致数据不一致的问题。为了解决这个问题,我们可以使用同步机制。

  1. 使用synchronized方法
package cn.juwatech.threads;

public class SynchronizedExample {
    private int count = 0;

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

    public static void main(String[] args) throws InterruptedException {
        SynchronizedExample example = new SynchronizedExample();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.println("Final count: " + example.count);
    }
}

在这个示例中,increment方法使用synchronized关键字进行同步,确保同一时间只有一个线程可以执行该方法。

  1. 使用synchronized代码块
package cn.juwatech.threads;

public class SynchronizedBlockExample {
    private int count = 0;
    private final Object lock = new Object();

    public void increment() {
        synchronized (lock) {
            count++;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedBlockExample example = new SynchronizedBlockExample();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.println("Final count: " + example.count);
    }
}

在这个示例中,我们使用synchronized代码块对increment方法进行同步,使用lock对象作为锁。

四、线程间的通信

在多线程环境中,线程间的通信是通过共享对象来完成的。Java提供了多种机制来实现线程间的通信,例如waitnotifynotifyAll方法。

package cn.juwatech.threads;

public class WaitNotifyExample {
    private final Object lock = new Object();

    public void produce() throws InterruptedException {
        synchronized (lock) {
            System.out.println("Producer is waiting...");
            lock.wait();
            System.out.println("Producer resumed.");
        }
    }

    public void consume() throws InterruptedException {
        synchronized (lock) {
            System.out.println("Consumer is working...");
            Thread.sleep(1000);
            lock.notify();
            System.out.println("Consumer notified.");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        WaitNotifyExample example = new WaitNotifyExample();

        Thread producer = new Thread(() -> {
            try {
                example.produce();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        Thread consumer = new Thread(() -> {
            try {
                example.consume();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        producer.start();
        Thread.sleep(100); // Ensure producer thread runs first
        consumer.start();

        producer.join();
        consumer.join();
    }
}

在这个示例中,produce方法会等待,直到它被consume方法通知。consume方法在执行完一定的工作后,会通知produce方法继续执行。

五、常见的线程安全问题

  1. 死锁:当两个或多个线程相互等待对方释放锁时,程序进入死锁状态,导致线程无法继续执行。
  2. 饥饿:当一个线程无法获得所需资源一直得不到执行机会时,程序进入饥饿状态。
  3. 活锁:当两个线程不断地相互改变对方的状态,导致程序无法继续执行。

为了避免这些问题,可以使用高级并发工具类,如ReentrantLockSemaphoreCountDownLatch等。

package cn.juwatech.threads;

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockExample example = new ReentrantLockExample();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.println("Final count: " + example.count);
    }
}

在这个示例中,我们使用ReentrantLock实现了对increment方法的同步。

总结

多线程编程是Java开发中一个重要且复杂的主题。本文详细介绍了Java中多线程的创建、线程的生命周期、线程的同步、线程间的通信以及常见的线程安全问题。通过掌握这些知识,我们可以编写出更加高效和健壮的多线程程序。

著作权归聚娃科技微赚淘客系统开发者团队,转载请注明出处!

标签:Java,Thread,void,example,详解,线程,new,多线程,public
From: https://www.cnblogs.com/szk123456/p/18300149

相关文章

  • Java中的线程通信详解
    Java中的线程通信详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在多线程编程中,线程之间的通信是一个重要且复杂的主题。为了确保多线程程序的正确性和效率,线程需要能够互相通信并协调工作。Java提供了多种方式来实现线程间的通信,如wait()、notify......
  • Java中标识符和关键字
    1.标识符publicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println("Hello,world");}}上述代码中在publicclass后面的HelloWorld称为类名,main称为方法名,也可以将其称为标识符,即:在程序中由用户给类名、方法名或者变量所取的名字。【......
  • 初识Java的main方法
    上文我们了解了Java语言的相关发展和Java的实用领域,此文我们从Java的main方法开始了解Java吧!1.main方法示例publicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println("Hello,world");}}图解:如上展示的就是最简单的一个Java程序,可......
  • Java异常详解及自定义异常
    认识异常,掌握异常处理主要的5个关键字:throw、try、catch、final、throws并掌握自定义异常目录1、异常概念与体系结构1、1异常的概念1、2异常体系结构 1、3异常的分类编译时异常:运行时异常:2、异常处理 2、1防御式编程2、2异常的抛出2.3异常的捕获2.3.1异常声......
  • 【java登录锁定功能】redis实现登录失败锁定账号
    登录失败(账号密码<5次时不提示),>=5次时,锁定时间5min,最高密码错误次数为10,第十次密码输入错误后,提醒,“账号已停用,请联系管理员开通”,次日0时,重新计算错误次数代码实现publicstaticStringLOGIN_FAIL_LOCK="login:error:count:";publicstaticStringLOGIN......
  • 【华为OD】D卷真题100分:内存资源分配 Java代码实现[思路+代码]
    【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript-CSDN博客JS、C、Java、python、C++代码实现:【华为OD】D卷真题100分:内存资源分配JavaScript代码实现[思路+代码]-C......
  • MYSQL 从入门到熟练 详解(看这一篇就够啦)
    一、MYSQL入门1.数据库概述(1)定义数据库(Database)是“按照数据结构来组织、存储和管理数据的仓库”。它是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据库中的数据按一定的数据模型组织、描述和存储,具有较小的数据冗余、较高的数据独立性和......
  • JAVA@Transactional常用失效场景
    @Transactional(rollbackFor={RuntimeException.class,Error.class})@Overridepublicbooleancreate(){create1();create2();returntrue;}publicvoidcreate1(){Studentstudent=newStudent();student.setNa......
  • JAVA初级之File文件类
    目录1、概述2、构造方法 3、常用方法3.1获取功能的方法 3.2绝对路径和相对路径 3.3判断功能的方法 3.4创建删除的方法 3.5对目录的遍历4、经典案例4.1查询某个目录下所有的文件。 4.2 找到电脑中所有以avi结尾的电影。1、概述        在......
  • windows使用bat文件 执行java程序
    java开发的程序想在windows上运行。首先要安装对应的java运行环境。然后创建一个 ***.bat文件,写入下面代码,双击它。@echoofftitleLSpbxServercd\d:cd"javaapp\LSpbxServer"java-jarLSpbxServer.jarpausetitleLSpbxServer是这个cmd.exe窗体的标题,同时......