不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • Java基础

  • 面向对象

  • Java进阶

    • 01.文件处理
    • 02.异常处理
    • 03.反射
    • 04.注解
    • 05.泛型
    • 06.日期与时间
    • 07.多线程基础
      • 01.多线程基础
        • 1、创建线程
        • 1、复写run
        • 2、传Runnable
        • 3、lambda语法
        • 2、线程传参
        • 3、线程超时退出
        • 4、守护线程
      • 02.线程同步
        • 0、线程非安全
        • 1、synchronized关键字
        • 2、Lock接口
        • 3、Atomic变量
        • 4、synchronized块
      • 03.锁
        • 0、死锁演示
        • 1、wait&notify
        • 2、ReentrantLock
        • 3、Condition
        • 4、ReentrantLock
        • 5、ReadWriteLock
        • 6、StampedLock
        • 7、Semaphore
    • 08.多线程进阶
    • 10.设计模式
  • Web基础

  • Spring框架

  • 微服务

  • Java
  • Java进阶
xiaonaiqiang
2024-04-30
目录

07.多线程基础

# 01.多线程基础

# 1、创建线程

# 1、复写run

  • 方法一:从Thread派生一个自定义类,然后覆写run()方法
public class Main {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start(); // 启动新线程
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("start new thread!");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2、传Runnable

  • 方法二:创建Thread实例时,传入一个Runnable实例
public class Main {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable());
        t.start(); // 启动新线程
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("start new thread!");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 3、lambda语法

public class Main {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println("start new thread!");
        });
        t.start(); // 启动新线程
    }
}
1
2
3
4
5
6
7
8

# 2、线程传参

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 4; i++) {
            int index = i; // 定义需要传递的参数
            Thread thread = new Thread(() -> runWithParameter(index));
            thread.start();
        }
    }

    private static void runWithParameter(int index) {
        System.out.println("Thread " + index + " is running.");
        // 在这里可以使用传入的参数
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 3、线程超时退出

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                // 模拟一个需要5秒钟才能完成的任务
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    System.out.println("Task interrupted!");
                    return;
                }
                System.out.println("Task completed!");
            }
        });
        t.start();
        // 等待3秒钟
        Thread.sleep(3000);
        // 如果任务还在执行,则中断任务
        if(t.isAlive()) {
            t.interrupt();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 4、守护线程

  • 主线程退出 守护线程就会退出
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    System.out.println("Daemon thread is running...");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.setDaemon(true); // 将线程t设置为守护线程
        t.start();
        Thread.sleep(5000); // 等待5秒钟
        System.out.println("Main thread is finished!");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 02.线程同步

# 0、线程非安全

  • count 加一操作,出现线程非安全问题的演示代码
public class Main {
    private static int count = 0;
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        count++;
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("count: " + count);  // count: 99525
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 1、synchronized关键字

  • synchronized 关键字修饰,表示在调用这些方法的时候,当前线程会获得对象的锁,其他线程只能等待,直到当前线程释放该对象锁
public class Main {

    private static int count = 0;
    public static synchronized void increment() {
        count++;
    }
    public static synchronized int value() {
        return count;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        // count++;
                        increment();
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("count: " + count);  // count: 99525
        System.out.println("count: " + value());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 2、Lock接口

  • lock 方法会让当前线程获得锁,如果锁已经被其他线程持有,当前线程就会等待
  • unlock 方法会释放当前线程持有的锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main {

    private static final Lock lock = new ReentrantLock();
    private static int count = 0;

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

    public void decrement() {
        lock.lock();
        try {
            count--;
        } finally {
            lock.unlock();
        }
    }

    public static int value() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        // count++;
                        increment();
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("count: " + count);  // count: 99525
        System.out.println("count: " + value());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

# 3、Atomic变量

  • incrementAndGet 和 decrementAndGet 方法都是原子操作,可以保证在多线程环境下的线程安全
import java.util.concurrent.atomic.AtomicInteger;

public class Main {

    private static AtomicInteger count = new AtomicInteger(0);

    public static void increment() {
        count.incrementAndGet();
    }

    public void decrement() {
        count.decrementAndGet();
    }

    public static int value() {
        return count.get();
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        // count++;
                        increment();
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("count: " + count);  // count: 99525
        System.out.println("count: " + value());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 4、synchronized块

  • synchronized 代码块会让当前线程获得 lock 对象的锁,其他线程只能等待,直到当前线程释放 lock 对象的锁
public class Main {
    private static int count = 0;
    private static Object lock = new Object();

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

    public void decrement() {
        synchronized (lock) {
            count--;
        }
    }

    public static int value() {
        synchronized (lock) {
            return count;
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        // count++;
                        increment();
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("count: " + count);  // count: 99525
        System.out.println("count: " + value());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 03.锁

# 0、死锁演示

  • 两个线程分别拥有资源1和资源2,但是它们都需要对方的资源才能继续执行
  • 因此,它们都在等待对方释放资源,从而导致死锁,下面代码如法结束
public class Main {
    public static void main(String[] args) {
        Object resource1 = new Object();
        Object resource2 = new Object();

        Thread thread1 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 1: Holding resource 1");

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

                System.out.println("Thread 1: Waiting for resource 2");

                synchronized (resource2) {
                    System.out.println("Thread 1: Holding resource 1 and 2");
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (resource2) {
                System.out.println("Thread 2: Holding resource 2");

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

                System.out.println("Thread 2: Waiting for resource 1");

                synchronized (resource1) {
                    System.out.println("Thread 2: Holding resource 1 and 2");
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

# 1、wait&notify

  • wait() 方法用于让一个线程等待,直到另一个线程通知它可以继续执行
  • notify() 方法用于通知等待在某个对象上的线程可以继续执行
public class Main {

    public static void main(String[] args) {

        final Object lock = new Object(); // 创建一个对象作为锁

        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 1: Acquired lock");
                try {
                    lock.wait(); // 在锁上等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread 1: Released lock");
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 2: Acquired lock");
                lock.notify(); // 唤醒在锁上等待的线程
                System.out.println("Thread 2: Released lock");
            }
        });

        thread1.start(); // 启动线程1
        try {
            Thread.sleep(1000); // 等待1秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread2.start(); // 启动线程2
    }
}
/*
Thread 1: Acquired lock
Thread 2: Acquired lock
Thread 2: Released lock
Thread 1: Released lock
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 2、ReentrantLock

  • ReentrantLock 创建了一个锁实例,并在两个线程中使用该锁实现了线程同步
  • 线程1和线程2分别获取锁、执行一些操作、等待1秒钟,然后释放锁
  • 由于锁是可重入的,因此线程可以多次获取同一个锁,而不会被阻塞
  • 需要注意的是,和 synchronized 关键字不同,ReentrantLock 必须显式地获取和释放锁
import java.util.concurrent.locks.ReentrantLock;

public class Main {
    public static void main(String[] args) {
        final ReentrantLock lock = new ReentrantLock(); // 创建一个 ReentrantLock 实例
        Thread thread1 = new Thread(() -> {
            lock.lock(); // 获取锁
            try {
                System.out.println("Thread 1: Acquired lock");
                Thread.sleep(1000); // 等待1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); // 释放锁
                System.out.println("Thread 1: Released lock");
            }
        });
        Thread thread2 = new Thread(() -> {
            lock.lock(); // 获取锁
            try {
                System.out.println("Thread 2: Acquired lock");
                Thread.sleep(1000); // 等待1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); // 释放锁
                System.out.println("Thread 2: Released lock");
            }
        });
        thread1.start(); // 启动线程1
        thread2.start(); // 启动线程2
    }
}
/*
Thread 1: Acquired lock

Thread 1: Released lock
Thread 2: Acquired lock

Thread 2: Released lock
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 3、Condition

  • Condition 可以让线程在等待某个条件满足时暂停执行,并在条件满足时重新开始执行
  • Condition 接口与 wait() 和 notify() 方法类似,但提供了更多的灵活性和控制性
package cls;

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

public class Main {
    public static void main(String[] args) {
        final ReentrantLock lock = new ReentrantLock(); // 创建一个 ReentrantLock 实例
        final Condition condition = lock.newCondition(); // 创建一个 Condition 实例
        Thread thread1 = new Thread(() -> {
            lock.lock(); // 获取锁
            try {
                System.out.println("Thread 1: Acquired lock");
                condition.await(); // 等待条件满足
                System.out.println("Thread 1: Resumed execution");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); // 释放锁
                System.out.println("Thread 1: Released lock");
            }
        });
        Thread thread2 = new Thread(() -> {
            lock.lock(); // 获取锁
            try {
                System.out.println("Thread 2: Acquired lock");
                Thread.sleep(1000); // 等待1秒钟
                condition.signal(); // 发出条件满足的信号
                System.out.println("Thread 2: Signalled condition");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); // 释放锁
                System.out.println("Thread 2: Released lock");
            }
        });
        thread1.start(); // 启动线程1
        thread2.start(); // 启动线程2
    }
}
/*
Thread 1: Acquired lock
Thread 2: Acquired lock

Thread 2: Signalled condition
Thread 2: Released lock
Thread 1: Resumed execution
Thread 1: Released lock
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 4、ReentrantLock

  • ReentrantLock 创建了一个锁实例,并在 getCount() 和 incrementCount() 方法中使用该锁实现了线程同步
  • getCount() 方法获取共享变量的值,而 incrementCount() 方法增加共享变量的值
  • 由于 ReentrantLock 是可重入的,因此线程可以多次获取同一个锁,而不会被阻塞
  • 需要注意的是,和 synchronized 关键字不同,ReentrantLock 必须显式地获取和释放锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main {

    private static final Lock lock = new ReentrantLock();
    private static int count = 0;

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

    public void decrement() {
        lock.lock();
        try {
            count--;
        } finally {
            lock.unlock();
        }
    }

    public static int value() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        // count++;
                        increment();
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("count: " + count);  // count: 99525
        System.out.println("count: " + value());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

# 5、ReadWriteLock

  • 由于 ReadWriteLock 允许多个线程同时读取共享资源,而只允许一个线程写入共享资源
  • 因此在多个线程同时调用 getCount() 方法时,可以有效地提高并发性能
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Main {

    private static final ReadWriteLock lock = new ReentrantReadWriteLock(); // 创建一个 ReadWriteLock 实例
    private static int count = 0; // 共享的变量
    public static int value() {
        lock.readLock().lock(); // 获取读锁
        try {
            return count; // 返回共享变量的值
        } finally {
            lock.readLock().unlock(); // 释放读锁
        }
    }
    public static void increment() {
        lock.writeLock().lock(); // 获取写锁
        try {
            count++; // 增加共享变量的值
        } finally {
            lock.writeLock().unlock(); // 释放写锁
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        // count++;
                        increment();
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("count: " + count);  // count: 99525
        System.out.println("count: " + value());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 6、StampedLock

  • StampedLock 是 Java 中提供的一种乐观读写锁机制,它可以提供比 ReadWriteLock 更高的并发性能
  • StampedLock 支持三种访问模式:读模式、写模式和乐观读模式
  • 在读模式下,多个线程可以同时读取共享资源,但不能写入共享资源
  • 在写模式下,只允许一个线程写入共享资源
  • 在乐观读模式下,线程可以读取共享资源,但需要在读取之前获取一个标记
  • 然后在读取完成之后检查标记是否仍然有效,如果仍然有效,则表示读取成功,否则需要重试读取
import java.util.concurrent.locks.*;

public class Main {
    private static final StampedLock lock = new StampedLock(); // 创建一个 StampedLock 实例
    private static int count = 0; // 共享的变量
    public static int value() {
        long stamp = lock.tryOptimisticRead(); // 尝试获取一个乐观读锁标记
        int value = count; // 读取共享变量的值
        if (!lock.validate(stamp)) { // 如果标记无效
            stamp = lock.readLock(); // 获取一个读锁
            try {
                value = count; // 重新读取共享变量的值
            } finally {
                lock.unlockRead(stamp); // 释放读锁
            }
        }
        return value; // 返回共享变量的值
    }
    public static void increment() {
        long stamp = lock.writeLock(); // 获取一个写锁
        try {
            count++; // 增加共享变量的值
        } finally {
            lock.unlockWrite(stamp); // 释放写锁
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // count++;
                    for (int j = 0; j < 1000; j++) increment();
                }
            }).start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("count: " + count);  // count: 99525
        System.out.println("count: " + value());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

# 7、Semaphore

  • Semaphore 是 Java 中提供的一种计数信号量机制,它可以控制同时访问共享资源的线程数量
  • Semaphore 维护了一个计数器,表示当前可用的许可证数量
  • 当一个线程要访问共享资源时,需要先获取一个许可证,如果许可证数量不足,则线程需要等待直到有许可证可用
  • 当一个线程使用完共享资源后,需要释放一个许可证,以便其他线程可以访问共享资源
package cls;

import java.util.concurrent.Semaphore;

public class Main {
    private final Semaphore semaphore = new Semaphore(2); // 创建一个 Semaphore 实例,初始许可证数量为2
    public void accessSharedResource() {
        try {
            semaphore.acquire(); // 获取一个许可证
            System.out.println(Thread.currentThread().getName() + " is accessing shared resource");
            Thread.sleep(1000); // 模拟访问共享资源的耗时
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // 释放一个许可证
            System.out.println(Thread.currentThread().getName() + " released a permit");
        }
    }
    public static void main(String[] args) {
        Main example = new Main();
        Thread thread1 = new Thread(() -> example.accessSharedResource(), "Thread 1");
        Thread thread2 = new Thread(() -> example.accessSharedResource(), "Thread 2");
        Thread thread3 = new Thread(() -> example.accessSharedResource(), "Thread 3");
        thread1.start(); // 启动线程1
        thread2.start(); // 启动线程2
        thread3.start(); // 启动线程3
    }
}
/*
Thread 2 is accessing shared resource
Thread 1 is accessing shared resource

Thread 3 is accessing shared resource
Thread 1 released a permit
Thread 2 released a permit

Thread 3 released a permit
 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
上次更新: 2024/5/31 11:18:42
06.日期与时间
08.多线程进阶

← 06.日期与时间 08.多线程进阶→

最近更新
01
04.数组双指针排序_子数组
03-25
02
08.动态规划
03-25
03
06.回溯算法
03-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式