相关文章推荐
粗眉毛的丝瓜  ·  从yocto配方中创建模拟链接 [关闭]·  2 年前    · 
空虚的啄木鸟  ·  Thinkphp中MySQL按照中文拼音排序 ...·  2 年前    · 
咆哮的青蛙  ·  备份链中断导致差异备份报错案例-阿里云开发者社区·  2 年前    · 
乐观的生姜  ·  教你使用caret包(一)--数据预处理 - 知乎·  2 年前    · 
Code  ›  八个经典的java多线程编程题目开发者社区
线程阻塞 try 线程 synchronized
https://cloud.tencent.com/developer/article/2030013
安静的油条
2 年前
作者头像
用户9854323
0 篇文章

八个经典的java多线程编程题目

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > 小陈飞砖 > 八个经典的java多线程编程题目

八个经典的java多线程编程题目

作者头像
用户9854323
发布 于 2022-06-25 10:58:32
437 0
发布 于 2022-06-25 10:58:32
举报

文章目录
  • 1、要求线程a执行完才开始线程b, 线程b执行完才开始线程
  • 2、两个线程轮流打印数字,一直到100
  • 3、写两个线程,一个线程打印1~ 52,另一个线程打印A~Z,打印顺序是12A34B...5152Z
  • 4、编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC...
  • 5、编写10个线程,第一个线程从1加到10,第二个线程从11加20…第十个线程从91加到100,最后再把10个线程结果相加。
  • 6 、三个窗口同时卖票
  • 7、 生产者消费者
    • 7.1 synchronized方式
    • 7.2 ReentrantLock方式 (可以保证顺序)
    • 7.3 BlockingQueue方式
    • 8、交替打印两个数组

1、要求线程a执行完才开始线程b, 线程b执行完才开始线程

package com.example.javatest.theardTest.MultiThreadAlgorithm;
 * 要求线程a执行完才开始线程b, 线程b执行完才开始线程
 * join()解释:https://blog.csdn.net/qq_18505715/article/details/79795728
 * wait()  和  notify()  解释:https://blog.csdn.net/chaozhi_guo/article/details/50249177
 * join()的作用:主要作用是同步,它可以使得线程之间的并行执行变为串行执行。在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。
 * public void joinDemo(){
 *    //....
 *    Thread t=new Thread(payService);
 *    t.start();
 *    //....
 *    //其他业务逻辑处理,不需要确定t线程是否执行完
 *    insertData();
 *    //后续的处理,需要依赖t线程的执行结果,可以在这里调用join方法等待t线程执行结束
 *    t.join();
public class T1T2T3 {
    public static class PrintThread extends Thread{
        PrintThread(String name){
            super(name);
        @Override
        public void run() {
            for(int i = 0; i < 100; i++){
                System.out.println(getName() + " : " + i);
    public static void main(String[] args){
        PrintThread t1 = new PrintThread("a");
        PrintThread t2 = new PrintThread("b");
        PrintThread t3 = new PrintThread("c");
        try {
            t1.start();
            t1.join();
            t2.start();
            t2.join();
            t3.start();
            t3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
 * 我对于join方法的理解:
 *    join() 的源码:
 *    public final void join(long millis) throws InterruptedException {
 *         synchronized(lock) {
 *         ...
 *           while (isAlive()) {
 *              lock.wait(0);
 *           }
 *        ...
 *         }
 *    }
 *    其实就是main()线程调用join()后,synchronized(lock)语句块,获得lock的锁,
 *    然后判断如果t1线程isAlive(), 就一直lock.wait(), 让自己(main()线程)阻塞住,
 *    直到t1线程 !isAlive 后才不wait, 等待着被notify(), 然后t1 die后会调用lock.notifyAll()。
 *    注意:这里lock.wait(0)虽然在t1.join()内,但是join()内的代码不是运行在t1线程中,而是运行在main()线程中,
 *          t1线程中运行的是其run()方法内的代码。
 */

2、两个线程轮流打印数字,一直到100

package com.example.javatest.theardTest.MultiThreadAlgorithm;
 * 两个线程轮流打印数字,一直到100
 * Java的wait()、notify()学习:
 * https://blog.csdn.net/boling_cavalry/article/details/77995069
public class TakeTurnsPrint {
    public static class TakeTurns {
        private static boolean flag = true;
        private static int count = 0;
        public synchronized void print1() {
            for (int i = 1; i <= 50; i++) {
                while (!flag) {
                    try {
                        System.out.println("print1: wait before");
                        wait();
                        System.out.println("print1: wait after");
                    } catch (InterruptedException e) {
                System.out.println("print1: " + ++count);
                flag = !flag;
                notifyAll();
        public synchronized void print2() {
            for (int i = 1; i <= 50; i++) {
                while (flag) {
                    try {
                        System.out.println("print2: wait before");
                        wait();
                        System.out.println("print2: wait after");
                    } catch (InterruptedException e) {
                System.out.println("print2: " + ++count);
                flag = !flag;
                notifyAll();
    public static void main(String[] args){
        TakeTurns takeTurns = new TakeTurns();
        new Thread(new Runnable() {
            @Override
            public void run() {
                takeTurns.print1();
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                takeTurns.print2();
        }).start();
}

3、写两个线程,一个线程打印1~ 52,另一个线程打印A~Z,打印顺序是12A34B…5152Z

package com.example.javatest.theardTest.MultiThreadAlgorithm;
 * 两线程,一个打印数字从1到52,另一个打印字母从A到Z,输出:12A34B56C...5152Z
public class TakeTurnsPrint2 {
    private boolean flag;
    private int count;
    public synchronized void printNum() {
        for (int i = 0; i < 26; i++) {
                while (flag) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                flag = !flag;
                System.out.print(++count);
                System.out.print(++count);
                notify();
    public synchronized void printLetter() {
        for (int i = 0; i < 26; i++) {
                while (!flag) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                flag = !flag;
                System.out.print((char) (65 + i));
                notify();
    public static void main(String[] args) {
        TakeTurnsPrint2 turnsPrint2 = new TakeTurnsPrint2();
        new Thread(new Runnable() {
            @Override
            public void run() {
                turnsPrint2.printNum();
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                turnsPrint2.printLetter();
        }).start();
}

4、编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC…

package com.example.javatest.theardTest.MultiThreadAlgorithm;
 * 编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC...
public class ABCABCABC {
    private int flag = 0;
    public synchronized void printA() {
        for(int i = 0; i < 5; i++) {
            while (flag != 0) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
            flag = 1;
            System.out.print("A");
            notifyAll();
    public synchronized void printB() {
        for(int i = 0; i < 5; i++) {
            while (flag != 1) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
            flag = 2;
            System.out.print("B");
            notifyAll();
    public synchronized void printC() {
        for(int i = 0; i < 5; i++) {
            while (flag != 2) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
            flag = 0;
            System.out.print("C");
            notifyAll();
    public static void main(String[] args) {
        ABCABCABC abcabcabc = new ABCABCABC();
        new Thread(new Runnable() {
            @Override
            public void run() {
                abcabcabc.printA();
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                abcabcabc.printB();
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                abcabcabc.printC();
        }).start();
}

5、编写10个线程,第一个线程从1加到10,第二个线程从11加20…第十个线程从91加到100,最后再把10个线程结果相加。

/**
 * 编写10个线程,第一个线程从1加到10,第二个线程从11加20…第十个线程从91加到100,最后再把10个线程结果相加
public class TenThreadSum {
    public static class SumThread extends Thread{
        int forct = 0;  int sum = 0;
        SumThread(int forct){
            this.forct = forct;
        @Override
        public void run() {
            for(int i = 1; i <= 10; i++){
                sum += i + forct * 10;
            System.out.println(getName() + "  " + sum);
    public static void main(String[] args) {
        int result = 0;
        for(int i = 0; i < 10; i++){
            SumThread sumThread = new SumThread(i);
            sumThread.start();
            try {
                sumThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            result = result + sumThread.sum;
        System.out.println("result   " + result);
}

6 、三个窗口同时卖票

/**
 * 三个窗口同时卖票
class Ticket {
    private int count = 1;
    public void sale() {
        while (true) {
            synchronized (this) {
                if (count > 200) {
                    System.out.println("票已经卖完啦");
                    break;
                } else {
                    System.out.println(Thread.currentThread().getName() + "卖的第 " + count++ + " 张票");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
 * 售票窗口
class SaleWindows extends Thread {
    private Ticket ticket;
    public SaleWindows(String name, Ticket ticket) {
        super(name);
        this.ticket = ticket;
    @Override
    public void run() {
        super.run();
        ticket.sale();
public class TicketDemo {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        SaleWindows windows1 = new SaleWindows("窗口1", ticket);
        SaleWindows windows2 = new SaleWindows("窗口2", ticket);
        SaleWindows windows3 = new SaleWindows("窗口3", ticket);
        windows1.start();
        windows2.start();
        windows3.start();
}

7、 生产者消费者

7.1 synchronized方式
public class FruitPlateDemo {
    private final static String LOCK = "lock";
    private int count = 0;
    private static final int FULL = 10;
    public static void main(String[] args) {
        FruitPlateDemo fruitDemo1 = new FruitPlateDemo();
        for (int i = 1; i <= 5; i++) {
            new Thread(fruitDemo1.new Producer(), "生产者-" + i).start();
            new Thread(fruitDemo1.new Consumer(), "消费者-" + i).start();
    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (LOCK) {
                    while (count == FULL) {
                        try {
                            LOCK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                    System.out.println("生产者 " + Thread.currentThread().getName() + " 总共有 " + ++count + " 个资源");
                    LOCK.notifyAll();
    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (LOCK) {
                    while (count == 0) {
                        try {
                            LOCK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                    System.out.println("消费者 " + Thread.currentThread().getName() + " 总共有 " + --count + " 个资源");
                    LOCK.notifyAll();
}
7.2 ReentrantLock方式 (可以保证顺序)
public class Demo1 {
    private int count = 0;
    private final static int FULL = 10;
    private Lock lock;
    private Condition notEmptyCondition;
    private Condition notFullCondition;
        lock = new ReentrantLock();
        notEmptyCondition = lock.newCondition();
        notFullCondition = lock.newCondition();
    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                lock.lock();
                try {
                    while(count == FULL) {
                        try {
                            notFullCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                    System.out.println("生产者 " + Thread.currentThread().getName() + " 总共有 " + ++count + " 个资源");
                    notEmptyCondition.signal();
                } finally {
                    lock.unlock();
    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                lock.lock();
                try {
                    while(count == 0) {
                        try {
                            notEmptyCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                    System.out.println("消费者 " + Thread.currentThread().getName() + " 总共有 " + --count + " 个资源");
                    notFullCondition.signal();
                } finally {
                    lock.unlock();
    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        for (int i = 1; i <= 5; i++) {
            new Thread(demo1.new Producer(), "生产者-" + i).start();
            new Thread(demo1.new Consumer(), "消费者-" + i).start();
}
7.3 BlockingQueue方式

BlockingQueue原理及其实现

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Demo2 {
    private int count = 0;
    private BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
    public static void main(String[] args) {
        Demo2 demo2 = new Demo2();
        for (int i = 1; i <= 5; i++) {
            new Thread(demo2.new Producer(), "生产者-" + i).start();
            new Thread(demo2.new Consumer(), "消费者-" + i).start();
    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    queue.put(1);
                    System.out.println("生产者 " + Thread.currentThread().getName() + " 总共有 " + ++count + " 个资源");
                } catch (InterruptedException e) {
                    e.printStackTrace();
    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    queue.take();
                    System.out.println("消费者 " + Thread.currentThread().getName() + " 总共有 " + --count + " 个资源");
                } catch (InterruptedException e) {
                    e.printStackTrace();
}
8、交替打印两个数组
package com.example.javatest.theardTest.MultiThreadAlgorithm;
public class TwoArr {
    int[] arr1 = new int[]{1, 3, 5, 7, 9};
    int[] arr2 = new int[]{2, 4, 6, 8, 10};
    boolean flag;
    public synchronized void print1(){
        for(int i= 0; i < arr1.length; i++){
            while (flag){
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
            flag = !flag;
            System.out.println(arr1[i]);
            notifyAll();
    public synchronized void print2(){
        for(int i= 0; i < arr2.length; i++){
            while (!flag){
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
            flag = !flag;
            System.out.println(arr2[i]);
            notifyAll();
    public static void main(String[] args) {
        TwoArr twoArr = new TwoArr();
        new Thread(new Runnable() {
            @Override
            public void run() {
                twoArr.print1();
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
 
推荐文章
粗眉毛的丝瓜  ·  从yocto配方中创建模拟链接 [关闭]
2 年前
空虚的啄木鸟  ·  Thinkphp中MySQL按照中文拼音排序问题的处理-腾讯云开发者社区-腾讯云
2 年前
咆哮的青蛙  ·  备份链中断导致差异备份报错案例-阿里云开发者社区
2 年前
乐观的生姜  ·  教你使用caret包(一)--数据预处理 - 知乎
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号