首页 > 编程语言 >java多线程(超详细!)

java多线程(超详细!)

时间:2024-07-29 18:50:06浏览次数:10  
标签:java Thread int void 线程 详细 new 多线程 public

Java 的多线程是一种允许在一个程序中同时运行多个线程的技术。每个线程是独立的执行路径,可以并发执行,从而提高程序的效率和响应能力。

1. 线程基础

Java 中的线程可以通过继承 Thread 类或实现 Runnable 接口来创建和管理。

1.1 继承 Thread

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

public class TestThread {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start(); // 启动线程
    }
}

run() 方法包含线程执行的代码,而 start() 方法用于启动新线程。

1.2 实现 Runnable 接口

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

public class TestRunnable {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread t1 = new Thread(myRunnable);
        t1.start(); // 启动线程
    }
}

通过实现 Runnable 接口的方式可以更灵活地共享资源。

2. 线程的生命周期

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

  • 新建(New): 线程对象被创建,但还没有调用 start() 方法。
  • 就绪(Runnable): 线程对象调用了 start() 方法,等待 CPU 调度。
  • 运行(Running): 线程获得 CPU,开始执行 run() 方法的代码。
  • 阻塞(Blocked): 线程因为某种原因(如等待资源、睡眠)被挂起。
  • 死亡(Dead): 线程执行完 run() 方法,或者因异常退出。

3. 线程控制

Java 提供了一些方法来控制线程的执行:

  • sleep(long millis):让当前线程睡眠指定的毫秒数。
  • join():等待该线程终止,也就是说等待当前的线程结束, 才会继续执行下面的代码
  • yield():暂停当前线程,让出 CPU 给其他线程。
  • interrupt():中断线程。

4. 线程同步

多线程程序中可能会出现多个线程同时访问共享资源的情况,导致数据不一致的问题。为了解决这个问题,可以使用同步技术。

4.1. ReentrantLock

ReentrantLock 提供了比 synchronized 更加灵活的锁机制,可以显式地锁定和解锁。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

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

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

    public int getCount() {
        return count;
    }
}

4.2. ReadWriteLock

ReadWriteLock 提供了一对锁,一个用于读操作,一个用于写操作。这允许多个读线程同时访问共享资源,但在写线程访问时会独占锁。

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockExample {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private int count = 0;

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

    public int getCount() {
        lock.readLock().lock();
        try {
            return count;
        } finally {
            lock.readLock().unlock();
        }
    }
}

4.3 synchronized

在方法前使用 synchronized 关键字,确保同一时间只有一个线程可以执行该方法。

class Counter {
    private int count = 0;

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

    public int getCount() {
        return count;
    }
}

4.4 同步块

同步块可以更灵活地控制需要同步的代码块,而不是整个方法。

class Counter {
    private int count = 0;

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

    public int getCount() {
        return count;
    }
}

4.5 注意事项

下面代码中的写法, 不能保证同一时间只有一个线程可以执行该方法。

因为 4.3 和 4.4 中 synchronized 的写法是根据 this 来保证同一时间只有一个线程可以执行, 但是他们的 this 是不同的。(把 "需要替换的" 换成注释上的就可以 "保证同一时间只有一个线程可以执行")

class Worker implements Runnable {
    public static int cnt = 0;

    @Override
    public synchronized void run() {
        for (int i = 0; i < 100000; i ++) {
            cnt ++;
        }
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
    
//        Worker worker = new Worker();
//        Thread t1 = new Thread(worker);
//        Thread t2 = new Thread(worker);

        Thread t1 = new Thread(new Worker());	// 需要替换
        Thread t2 = new Thread(new Worker());	// 需要替换

        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println(Worker.cnt);
    }
}

当然, 4.4 的代码也可以写成下面这样,这样他就是根据 lock 这个对象来保证同步的, java中的对象都可以当作lock

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

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

    public int getCount() {
        return count;
    }
}

5. 线程通信

Java 提供了 wait(), notify(), notifyAll() 方法来实现线程间的通信。

  • wait():让当前线程等待,直到其他线程调用 notify()notifyAll()
  • notify():唤醒一个正在等待的线程。
  • notifyAll():唤醒所有正在等待的线程。

6. 线程池

使用线程池可以有效地管理和复用线程,减少创建和销毁线程的开销。Java 提供了 Executor 框架来管理线程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThreadPool {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            executor.execute(new MyRunnable());
        }
        executor.shutdown();
    }
}

7. 高级线程工具

Java 提供了很多高级线程工具,如 Semaphore, CountDownLatch, CyclicBarrier 等,用于复杂的线程协调和同步。

7.1 Semaphore

信号量控制同时访问特定资源的线程数量。

import java.util.concurrent.Semaphore;

public class TestSemaphore {
    private static final Semaphore semaphore = new Semaphore(3);

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new Task()).start();
        }
    }

    static class Task implements Runnable {
        public void run() {
            try {
                semaphore.acquire();
                System.out.println("Thread " + Thread.currentThread().getName() + " is accessing the resource.");
                Thread.sleep(2000);
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

7.2 CountDownLatch

允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。

import java.util.concurrent.CountDownLatch;

public class TestCountDownLatch {
    private static final int THREAD_COUNT = 3;
    private static final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            new Thread(new Task()).start();
        }
        try {
            latch.await(); // 主线程等待所有子线程完成
            System.out.println("All threads have finished.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class Task implements Runnable {
        public void run() {
            System.out.println("Thread " + Thread.currentThread().getName() + " is working.");
            latch.countDown(); // 计数器减一
        }
    }
}

结论

Java 多线程是一个强大且复杂的技术,需要深入理解和小心使用,以避免潜在的并发问题和死锁情况。通过合理地利用线程同步、线程通信和线程池等工具,可以编写高效且安全的多线程应用程序。

标签:java,Thread,int,void,线程,详细,new,多线程,public
From: https://www.cnblogs.com/xxctx/p/18330812

相关文章

  • unity游戏源码和配套教程:三维的美好场景,完全免费和开源,教程完整详细,适合初学者入门
    源码(含配套教程)在夸克网盘(完全免费,完全开源,完整详细):夸克网盘分享夸克网盘是夸克推出的一款云服务产品,功能包括云存储、高清看剧、文件在线解压、PDF一键转换等。通过夸克网盘可随时随地管理和使用照片、文档、手机资料,目前支持Android、iOS、PC、iPad。https://pan.quark.cn/s/......
  • Adobe2024全家桶下载+详细安装教程
    “我电脑里安装了20多个Adobe软件,但真正用到的只有PS。”近日,有网友在社交平台发帖称,自己的电脑里安装了大量Adobe软件,但实际上只经常使用Photoshop。对此,有其他网友回复道:“你这是买椟还珠,Adobe全家桶里有很多宝藏工具,比如AE、PR、AU等。”Adobe全家桶永久免费领取入口:http......
  • java
    第一章java概念和开发注意事项java特点Java语言是面向对象的(oop)Java语言是健壮的。java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证Java语言是跨平台性的[即:一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台]根本原因是JVM是j......
  • 华为OD笔试机试 - 园区参观路径 (Java 2024年C卷D卷真题算法)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述园区某部门举办了FamilyDay,邀请员工及其家属参加;将公司园区视为一个矩形,起始园区设置在左上角,终点园区设置在右下角;家属参观园区时,只能向右和向下园区前进,求从起始园区到终点园区会有多少条不同的参观路径......
  • Java计算机毕业设计旅游购票系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着旅游业的蓬勃发展,游客对于旅游体验的需求日益多样化与便捷化。传统的购票方式,如现场排队购票,不仅耗时耗力,还常常因票源紧张而影响游客的行程安排......
  • 华为OD笔试机试真题算法 - 密码解密 (Java 2024年C卷D卷)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述给定一段“密文”字符串s,其中字符都是经过“密码本”映射的,现需要将“密文”解密并输出。映射的规则(‘a’~‘i’)分别用(‘1’~‘9’)表示;(‘j’~‘z’)分别用(“10*”~“26*”)表示。约束:映射始终唯一。......
  • Java计算机毕业设计旅游网站设计(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在全球化与数字化浪潮的推动下,旅游业迎来了前所未有的发展机遇。随着人们生活水平的提高和休闲方式的多样化,旅游需求日益增长,对旅游信息的获取与预订......
  • Java计算机毕业设计酒店客房管理信息系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着旅游业的蓬勃发展,酒店行业面临着前所未有的挑战与机遇。传统的酒店客房管理方式往往依赖于人工记录与操作,效率低下且易出错,难以满足现代酒店业对......
  • Java计算机毕业设计基于校园失物招领系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在繁忙的校园生活中,失物与拾物的情况时有发生,传统的失物招领方式往往依赖于公告板、微信群或口头传播,这些方式不仅效率低下,而且覆盖范围有限,导致许多......
  • 基于javaweb的家乡旅游网站的设计与实现
    摘 要随着社会经济的持续发展和人民生活水平的提高,旅游已经成为人们生活中不可或缺的重要组成部分。同时,互联网的普及,让人们对于旅游信息的获取逐渐转移到线上平台。基于javaweb的家乡旅游网站作为一个便捷的家乡旅游资讯信息的平台,为用户提供了实时且全面的家乡旅游信息,包......