面试题-多线程汇总

Posted by lichao modified on June 22, 2022

多线程循环打印123

启动 3 个线程,线程 1 无限循环打印 1、线程 2 无限循环打印 2、线程 3 无限循环打印 3,要求按 123123… 顺序循环打印;

方法一:利用ReentrantLock的多Condition实现线程间通信:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class NumberPrint1 {
    public static void main(String[] args) throws Exception {
        ReentrantLock lock = new ReentrantLock();
        Condition c1 = lock.newCondition();
        Condition c2 = lock.newCondition();
        Condition c3 = lock.newCondition();
        new Thread(new PrintTask(lock, c1, c2, ";1";)).start();
        new Thread(new PrintTask(lock, c2, c3, ";2";)).start();
        new Thread(new PrintTask(lock, c3, c1, ";3";)).start();
        try {
            lock.lock();
            c1.signal();
        } finally {
            lock.unlock();
        }
        Thread.sleep(Integer.MAX_VALUE);
    }
    
    static class PrintTask implements Runnable {
        private ReentrantLock lock;
        private Condition condition;
        private Condition conditionNext;
        private String str;
        public PrintTask(ReentrantLock lock, Condition condition, Condition conditionNext, String str) {
            this.lock = lock;
            this.condition = condition;
            this.conditionNext = conditionNext;
            this.str = str;
        }
        @Override
        public void run() {
            while(true) {
                try {
                    lock.lock();
                    condition.await();
                    System.out.println(str);
                    conditionNext.signal();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

方法二:利用volatile关键字实现线程间通信:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class NumberPrint2 {

    static volatile int flag = 1;

    public static void main(String[] args) throws Exception {
        new Thread(new PrintTask(";1";, 1, 2)).start();
        new Thread(new PrintTask(";2";, 2, 3)).start();
        new Thread(new PrintTask(";3";, 3, 1)).start();

        Thread.sleep(Integer.MAX_VALUE);
    }

    static class PrintTask<t> implements Runnable {
        private String str;
        private int curr;
        private int next;
        public PrintTask(String str, int curr, int next){
            this.str = str;
            this.curr = curr;
            this.next = next;
        }
        @Override
        public void run() {
            while(true){
                if(flag == curr){
                    System.out.println(str);
                    flag = next;
                }
            }
        }
    }
}

方法三:利用锁的wait和notify机制实现线程间通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class NumberPrint3 {
    static Object o1 = new Object();
    static Object o2 = new Object();
    static Object o3 = new Object();

    public static void main(String[] args) throws Exception {
        new Thread(new PrintTask(";1";, o1, o2)).start();
        new Thread(new PrintTask(";2";, o2, o3)).start();
        new Thread(new PrintTask(";3";, o3, o1)).start();

        synchronized (o1) {
            o1.notify();
        }

        Thread.sleep(Integer.MAX_VALUE);
    }

    static class PrintTask implements Runnable {
        private Object curr;
        private Object next;
        private String str;
        public PrintTask(String str, Object curr, Object next){
            this.str = str;
            this.curr = curr;
            this.next = next;
        }
        @Override
        public void run() {
            while(true){
                synchronized (curr) {
                    try {
                        curr.wait();
                        System.out.println(str);
                        synchronized (next) {
                            next.notify();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

方法四:利用cas机制实现线程间通信:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.concurrent.atomic.AtomicInteger;

public class NumberPrint4 {

    static AtomicInteger flag = new AtomicInteger(1);

    public static void main(String[] args) throws Exception {
        new Thread(new PrintTask(";1";, 1, 2)).start();
        new Thread(new PrintTask(";2";, 2, 3)).start();
        new Thread(new PrintTask(";3";, 3, 1)).start();

        Thread.sleep(Integer.MAX_VALUE);
    }

    static class PrintTask<t> implements Runnable {
        private String str;
        private int curr;
        private int next;
        public PrintTask(String str, int curr, int next){
            this.str = str;
            this.curr = curr;
            this.next = next;
        }
        @Override
        public void run() {
            while(true){
                if(flag.get() == curr){
                    System.out.println(str);
                    flag.set(next);
                }
            }
        }
    }
}