多线程面试题_1.三个线程依次打印ABC...2.两个线程交替打印AB,3.生产者消费者

Q:(手写算法)用三个线程,线程“1”,“2”, “3”,顺序打印字母A-Z,输出结果是1A、2B、3C、1D 2E… ?

  • 方法1
package com.nancy.base;

public class PrintABC {

    private static char c = 'A';
    private static int i = 0;

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    try{
                        int threadId =
                                Integer.parseInt(Thread.currentThread().getName());
                        while (i < 26) {
                            if(i % 3 == threadId - 1) {
                                System.out.println(threadId + " " + (char) c++);
                                i++;
                                notifyAll();
                            }else {
                                wait();
                            }
                        }
                    }catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }

        };
        Thread t1 = new Thread(runnable, "1");
        Thread t2 = new Thread(runnable, "2");
        Thread t3 = new Thread(runnable, "3");

        t1.start();
        t2.start();
        t3.start();
        
    }
}

1A,2B,3C,1D,2E,3F,1G,2H,3I,1J,2K,3L,1M,2N,3O,1P,2Q,3R,1S,2T,3U,1V,2W,3X,1Y,2Z,

  • 方法2
package com.nancy.base;

public class PrintABC2 {

    public static int i = 26;
    public static Foo foo = new Foo();

    public static void main(String[] args) {
        new Thread(() -> {
            while (i-- > 0) {
                foo.print1();
            }
        }, "1").start();

        new Thread(() -> {
            while (i-- > 0) {
                foo.print2();
            }
        }, "2").start();

        new Thread(() -> {
            while (i-- > 0) {
                foo.print3();
            }
        }, "3").start();
    }
}


class Foo {

    private int flag = 0;
    private char c = 'A';

    public void print1() {
        synchronized (this) {
            try {
                while (this.flag != 0) {
                    wait();
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print(Thread.currentThread().getName() + "" +
                    (char)c++ + ",");
            flag = 1;
            notifyAll();
        }
    }

    public void print2() {
        synchronized (this) {
            try {
                while (this.flag != 1) {
                    wait();
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print(Thread.currentThread().getName() + "" +
                    (char)c++ + ",");
            flag = 2;
            notifyAll();
        }
    }

    public void print3() {
        synchronized (this) {
            try {
                while (this.flag != 2) {
                    wait();
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print(Thread.currentThread().getName() + "" +
                    (char)c++ + ",");
            flag = 0;
            notifyAll();
        }
    }
}

1A,2B,3C,1D,2E,3F,1G,2H,3I,1J,2K,3L,1M,2N,3O,1P,2Q,3R,1S,2T,3U,1V,2W,3X,1Y,2Z,

两个线程交替打印AB,总共10次

  • 方法1
package com.nancy.base;

public class PrintAB {


    private static int flag = 1;
    private static int i = 0;

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    try {
                        int threadId = Integer.parseInt(
                                Thread.currentThread().getName()
                        );
                        while (i < 10) {
                            if(i % 2 == threadId - 1) {
                                System.out.print(threadId + "" + (flag == 1 ? 'A' : 'B') + ",");
                                i++;
                                flag = -flag;
                                notifyAll();
                            }else {
                                wait();
                            }
                        }
                    }catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t1 = new Thread(runnable, "1");
        Thread t2 = new Thread(runnable, "2");

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

1A,2B,1A,2B,1A,2B,1A,2B,1A,2B,

  • 方法2
public class PrintAB2 {

    public static int DEFUALT_TIMES = 5;

    public static void main(String[] args) {
        GuardObject lock = new GuardObject();

        new Thread(() -> {
            int i = DEFUALT_TIMES;
            while (i-- > 0) {
                lock.printA();
            }
        }, "1").start();

        new Thread(() -> {
            int i = DEFUALT_TIMES;
            while (i-- > 0) {
                lock.printB();
            }
        }, "2").start();

    }
}


class GuardObject {
    private boolean flag = true;

    public void printA() {
        synchronized (this) {
            while (!this.flag) {
                try {
                    this.wait();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.print(Thread.currentThread().getName() + "A" + ",");
            flag = false;
            notifyAll();
        }
    }

    public void printB() {
        synchronized (this) {
            while (this.flag) {
                try {
                    this.wait();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.print(Thread.currentThread().getName() + "B" + ",");
            flag = true;
            notifyAll();
        }
    }
}

1A,2B,1A,2B,1A,2B,1A,2B,1A,2B,

生产者消费者

public class ProductConsumerTest {

    public static void main(String[] args) {
        Resources r = new Resources();

        ProductThread t1 = new ProductThread(r);
        ConsumerThread t2 = new ConsumerThread(r);

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


class Resources {

    private int[] arr = new int[5];
    private int count = 0;

    synchronized public void product() throws Exception{
        if(count == arr.length) {
            wait();
        }else {
            int m = (int)Math.floor(Math.random()*10 + 1);
            arr[count] = m;
            count++;
            System.out.println("生产:" + m);

            notifyAll();
        }
    }

    synchronized public void consume() throws Exception {
        if(count == 0) {
            wait();
        }else {
            int n = arr[count-1];
            arr[count-1] = 0;
            count--;
            System.out.println("消费:" + n);
            notifyAll();
        }
    }
 }

 class ProductThread extends Thread {
    private Resources r;
    public ProductThread(Resources r) {
        this.r = r;
    }
    public void run() {
        try {
            while (true) {
                r.product();
                Thread.sleep(1);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
 }


 class ConsumerThread extends Thread {
    private Resources r;

    public ConsumerThread(Resources r) {
        this.r = r;
    }

    public void run() {
        try {
            while (true) {
                r.consume();
                Thread.sleep(1);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
 }
  • 简洁版
public class ProductConsumerTest {

    public static void main(String[] args) {
        Resources r = new Resources();

        new Thread(() -> {
            try {
                while (true) {
                    r.product();
                    Thread.sleep(1);
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "生产者").start();

        new Thread(() -> {
            try {
                while (true) {
                    r.consume();
                    Thread.sleep(1);
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "消费者").start();
    }
}


class Resources {

    private int[] arr = new int[5];
    private int count = 0;

    synchronized public void product(){
        try {
            while (count == arr.length) {
                wait();
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }

        int m = (int)Math.floor(Math.random()*10 + 1);
        arr[count] = m;
        count++;
        System.out.println("生产:" + m);
        notifyAll();
    }

    synchronized public void consume() {
        try {
            while (count == 0) {
                wait();
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
        int m = arr[count-1];
        count--;
        System.out.println("消费:" + m);
        notifyAll();
    }
}

你可能感兴趣的:(多线程)