跳至主要內容

JAVA多线程代码题

holic-x...大约 3 分钟JAVA基础

JAVA多线程代码题

学习资料

1.写一个双线程轮流打印1-100

思路1:传统wait/notifyAll + 等待标记mark

class ThreadDemo1_01 {

    static AtomicInteger count = new AtomicInteger(1); // 定义计数器
    static Object lock = new Object(); // 定义对象锁
    static int mark = 1; // 定义全局等待标记(1-线程A执行;2-线程B执行)

    public static void main(String[] args) {
        // 线程A定义
        Thread ta = new Thread(() -> {
            while (count.get() < 100) {
                synchronized (lock) {
                    while (mark != 1) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.println("线程A执行" + count.getAndIncrement()); // 打印并执行自增操作
                    lock.notifyAll(); // 唤醒
                    mark = 2; // 切换等待标记
                }
            }
        });

        // 线程B定义
        Thread tb = new Thread(() -> {
            while (count.get() <= 100) {
                synchronized (lock) {
                    while (mark != 2) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.println("线程B执行" + count.getAndIncrement()); // 线程B打印信息
                    lock.notifyAll(); // 唤醒
                    mark = 1; // 切换等待标记
                }
            }
        });
        // 启动线程
        ta.start();
        tb.start();
    }
}

思路2:信号量Semaphore

class ThreadDemo1_02 {

    static AtomicInteger count = new AtomicInteger(1); // 定义计数器
    static Semaphore s1 = new Semaphore(1);
    static Semaphore s2 = new Semaphore(0);

    public static void main(String[] args) {
        // 线程A定义
        Thread ta = new Thread(() -> {
           try{
               while(count.get() < 100) {
                   s1.acquire();
                   System.out.println("线程A执行" + count.getAndIncrement());
                   s2.release();
               }
           }catch (Exception e){
               e.printStackTrace();
           }
        });

        // 线程B定义
        Thread tb = new Thread(() -> {
            try{
                while(count.get() < 100) {
                    s2.acquire();
                    System.out.println("线程B执行" + count.getAndIncrement());
                    s1.release();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        });

        ta.start();
        tb.start();
    }
}

思路3:LockSupport

class ThreadDemo1_03 {
    static AtomicInteger count = new AtomicInteger(1); // 定义计数器
    static Thread[] threads = new Thread[2];
    public static void main(String[] args) {
        threads[0] = new Thread(()->{
            while(count.get() < 100) {
                System.out.println("线程A执行" + count.getAndIncrement());
                LockSupport.unpark(threads[1]);
                LockSupport.park();
            }
        });

        threads[1] = new Thread(()->{
            while(count.get() < 100) {
                LockSupport.park();
                System.out.println("线程B执行" + count.getAndIncrement());
                LockSupport.unpark(threads[0]);
            }
        });
        threads[0].start();
        threads[1].start();
    }
}

同题目:【2个线程,交替打印1-100的奇偶数】

​ 其本质上是一样的概念,但此处需做额外的奇数、偶数判断(此处以思路2进行参考),对比思路2代码,其在内存嵌套中多加了个while判断,用于明确限定奇数、偶数

class ThreadDemo1_04 {
    static AtomicInteger count = new AtomicInteger(1); // 定义计数器
    static Semaphore s1 = new Semaphore(1);
    static Semaphore s2 = new Semaphore(0);
    public static void main(String[] args) {
        // 线程A打印奇数
        Thread ta = new Thread(() -> {
            while (count.get() < 100) {
                while (count.get() % 2 == 1) {
                    try {
                        s1.acquire();
                        System.out.println("[奇数]线程A执行" + count.getAndIncrement());
                        s2.release();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        // 线程B打印偶数
        Thread tb = new Thread(() -> {
            while (count.get() <= 100) {
                while (count.get() % 2 == 0) {
                    try {
                        s2.acquire();
                        System.out.println("[偶数]线程B执行" + count.getAndIncrement());
                        s1.release();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        ta.start();
        tb.start();
    }
}

2.三个线程顺序打出1-100

3.多线程问题:线程A,B、C,分别打印1、2、3,顺序执行10次

4.计数累加怎么线程安全,可以怎么实现,100个线程,每个线程累加100次

5.线程交叉打印12A34B56C,多种实现方式(一个打印数字,一个打印字母)

6.两个线程交替打印ABCD..Z字母,一个大写一个小写

7.两个线程交替打印出a1b2c3.....z26

8.两个线程,一个打印abcd,一个打印1234,需求交替打印出a1b2c3d4a1b2c3d4; 打印10轮

9.假设有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?目前有500张票,同时有1~44个购票窗口,模拟购票流程,打印购票结果,比如:从1窗口购买1张

10.模仿购票系统,票,剩余499张票

11.有一批任务Tasks,现在我需要实现按批次执行,并且批次可以动态指定,例如[1,3,5,7]第一批执行,[11,13,15,17]第二批执行,…,最后没有指定的任务就最后一起执行掉。批次之间需要按顺序,前一批执行完了才执行下一批

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3