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

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() {
                twoArr.print2();
            }
        }).start();
    }

}

以下是两个基于 Java 的网络编程多线程编程题,以及对应的模板和答案,供参考: #### 题一:多线程 TCP 服务器 要求:实现一个多线程 TCP 服务器,能够同时处理多个客户端的请求。服务器接收到客户端的请求后,将请求信息返回给客户端,并显示客户端的 IP 地址和端口号。 ##### 模板: ```java import java.io.*; import java.net.*; public class MultiThreadTCPServer { public static void main(String[] args) { try { // 创建 ServerSocket 对象 ServerSocket serverSocket = new ServerSocket(<服务器端口号>); while (true) { // 等待客户端连接 Socket socket = serverSocket.accept(); // 创建新线程处理客户端请求 Thread thread = new Thread(() -> { try { // 获取输入输出流 InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); PrintWriter pw = new PrintWriter(os); // 接收数据 String request = br.readLine(); System.out.println("收到来自 " + socket.getInetAddress() + ":" + socket.getPort() + " 的请求:" + request); // 发送数据 pw.println("收到您的请求:" + request); pw.flush(); // 关闭连接 br.close(); pw.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }); thread.start(); } } catch (IOException e) { e.printStackTrace(); } } } ``` ##### 答案: 上面的模板中,我们通过 ServerSocket 类创建了一个 TCP 服务器,并指定了服务器的端口号。然后,我们通过 while 循环等待客户端的连接请求。当有新的客户端连接时,我们创建一个新线程来处理客户端的请求。在新线程中,我们通过输入输出流进行数据的发送和接收。在接收数据时,我们通过 BufferedReader 对象读取输入流中的数据,并通过 InetAddress 和 getPort 方法获取客户端的 IP 地址和端口号。在发送数据时,我们将数据写入 PrintWriter 对象中,再通过 flush 方法将数据发送出去。最后,我们通过关闭输入输出流和 Socket 对象来关闭连接。 #### 题二:多线程 TCP 客户端 要求:实现一个多线程 TCP 客户端,能够向服务器发送多个请求,并显示服务器的响应信息。 ##### 模板: ```java import java.io.*; import java.net.*; public class MultiThreadTCPClient { public static void main(String[] args) { try { // 创建 Socket 对象 Socket socket = new Socket("<服务器IP地址>", <服务器端口号>); // 创建多个线程发送请求 for (int i = 0; i < <线程数量>; i++) { Thread thread = new Thread(() -> { try { // 获取输入输出流 InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); PrintWriter pw = new PrintWriter(os); // 发送数据 pw.println("<发送的数据>"); pw.flush(); // 接收数据 String response = br.readLine(); System.out.println("收到服务器响应:" + response); // 关闭连接 br.close(); pw.close(); } catch (IOException e) { e.printStackTrace(); } }); thread.start(); } // 关闭连接 socket.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` ##### 答案: 上面的模板中,我们通过 Socket 类创建了一个 TCP 连接,并指定了服务器的 IP 地址和端口号。然后,我们创建多个线程来发送请求,每个线程都通过输入输出流进行数据的发送和接收。在发送数据时,我们将数据写入 PrintWriter 对象中,再通过 flush 方法将数据发送出去。在接收数据时,我们通过 BufferedReader 对象读取输入流中的数据,并显示服务器的响应信息。最后,我们通过关闭输入输出流和 Socket 对象来关闭连接。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值