JAVA并发编程练习题

前言

学了几天的多线程基础部分,书上的东西一看就懂,但是真的实践还是值得推敲的

题目

1、写一个程序,线程C在线程B后执行,线程B在线程A之后进行

package thread;

public class Test {

    public static void main(String[] args) {
        Thread threadA = new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("This is A");
            }
        });

        Thread threadB = new Thread(() -> {
            try {
                threadA.join();
            } catch (Exception e) {
                // TODO: handle exception
            }
            System.out.println("This is B");
        });

        Thread threadC = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    threadB.join();
                } catch (Exception e) {
                    // TODO: handle exception
                }
                System.out.println("This is C");
            }
        });
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

或者这样

package thread;

public class Test2 {
    public static void main(String[] args) {
        Thread aThread = new Thread(() -> {
            System.out.println("This is A");
        });
        Thread bThread = new Thread(() -> {
            System.out.println("This is B");
        });
        Thread cThread = new Thread(() -> {
            System.out.println("This is C");
        });
        try {
            aThread.start();
            aThread.join();
            bThread.start();
            bThread.join();
            cThread.start();
            cThread.join();
        } catch (Exception e) {
            // TODO: handle exception
        }

    }
}

2、编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

第一次代码

package thread;

public class Test4 {
    public static void main(String[] args) {
        Thread threadA = new Thread(() -> {
            System.out.println("This is A");
        });

        Thread threadB = new Thread(() -> {
            try {
                threadA.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("This is B");
        });

        Thread threadC = new Thread(() -> {
            try {
                threadB.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("This is C");
        });

        for (int i=0;i<10;i++) {
            threadA.start();
            threadB.start();
            threadC.start();
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
---output----
This is A
This is B
This is C
Exception in thread "main" java.lang.IllegalThreadStateException
    at java.base/java.lang.Thread.start(Thread.java:804)
    at thread.Test4.main(Test4.java:30)

分析:
一开始我以为是执行地太快了,在main里面sleep了一会,结果发现还是崩了,最后google才发现,原来同样的线程不能循环执行,这和线程的生命周期有关系。销毁了之后就不能再进行了。

第二次代码

package thread;

public class Test3 {
    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            Thread threadA = new Thread(() -> {
                System.out.println(Thread.currentThread().getName());
            }, "A");

            Thread threadB = new Thread(() -> {
                try {
                    threadA.join();
                    System.out.println(Thread.currentThread().getName());
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }, "B");

            Thread threadC = new Thread(() -> {
                try {
                    threadB.join();
                    System.out.println(Thread.currentThread().getName());
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }, "C");



            threadC.start();
            threadB.start();
            threadA.start();
            try {
                Thread.sleep(300);
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
}

分析:
这里的sleep比较重要,因为每次都new了一个线程,主线程执行地太快,会导致新的线程先于旧线程的顺序执行。类似于插队了。但是我觉得这里new了多个线程不太好,为什么不用3个线程直接完成呢?好像不符合题目的开启3个线程这个条件

第三次代码

package thread;

public class Test {
    public static class Worker {
        Object lock = new Object();
        int flag = 1;

        public void PrintA() {
            synchronized (lock) {
                while (flag != 1) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // TODO: handle exception
                    }
                }
                flag = 2;
                lock.notifyAll();
                System.out.println(Thread.currentThread().getName());
            }
        }

        public void PrintB() {
            synchronized (lock) {
                while (flag != 2) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // TODO: handle exception
                    }
                }
                flag = 3;
                lock.notifyAll();
                System.out.println(Thread.currentThread().getName());
            }
        }

        public void PrintC() {
            synchronized (lock) {
                while (flag != 3) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // TODO: handle exception
                    }
                }
                flag = 1;
                lock.notifyAll();
                System.out.println(Thread.currentThread().getName());
            }
        }

    }

    public static void main(String[] args) {
        Worker worker = new Worker();

        Thread threadA = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                worker.PrintA();
            }
        }, "A");
        Thread threadB = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                worker.PrintB();
            }
        }, "B");
        Thread threadC = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                worker.PrintC();
            }
        }, "C");

        threadA.start();
        threadB.start();
        threadC.start();
    }
}

你可能感兴趣的:(java并发)