n个线程按顺序输出1到100(三种方法)

n个线程按顺序输出1到100的三种方法

代码均用java实现,经测试无误。

方法一

在循环中中判断是否该自己输出了,是的话就输出,不是的话就进入下一个循环,当即将输出的数字超过100,循环结束。
用synchronize加锁保证cnt++的原子性

public class Test4 extends Thread {
    static int n = 6; // 线程数量
    static volatile int cnt = 0; // 计数,到100结束

    private int id;  // 线程编号
    public Test4(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        while (cnt <= 100) {
            if (cnt % n == id) {
                synchronized (Test4.class) {
                    cnt++;
                    if(cnt > 100){
                        break;
                    }
                    System.out.println("thread_" + id + " cnt:" + cnt);
                }
            }
        }
    }

    public static void main(String[] args) {
        for(int i = 0; i < n; i++){
            new Test4(i).start();
        }
    }
}

方法二

用等待唤醒机制,当一个线程执行完当前任务后再唤醒其他线程来执行任务,自己去休眠,避免在线程执行任务的时候其他线程处于忙等状态,浪费cpu资源。

package multiThread;

public class Test4 extends Thread {
    static int n = 6; // 线程数量
    static volatile int cnt = 0; // 计数,到100结束

    private int id;  // 线程编号
    public Test4(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        while (cnt <= 100) {
            synchronized (Test4.class) {
                if (cnt % n == id){
                    cnt++;
                    if(cnt > 100){
                        Test4.class.notify();
                        break;
                    }
                    System.out.println("thread_" + id + " cnt:" + cnt);
                    Test4.class.notify();
                    try {
                        Test4.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        for(int i = 0; i < n; i++){
            new Test4(i).start();
        }
    }
}

方法三

用 ReentrantLock 来解决,本质和解法二一样,不过是用synchronized 换成 lock 来实现,等待唤醒机制用 signal 和 await来实现

package multiThread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test4 extends Thread {
    static Lock lock = new ReentrantLock();
    static Condition condition = lock.newCondition();

    static int n = 6; // 线程数量
    static volatile int cnt = 0; // 计数,到100结束

    private int id;  // 线程编号
    public Test4(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        while (cnt <= 100) {
            lock.lock();
            while (cnt % n == id){
                cnt++;
                if(cnt > 100){
                    condition.signalAll();
                    break;
                }
                System.out.println("thread_" + id + " cnt:" + cnt);
                condition.signal();
                try {
                    condition.await();
                    if(cnt > 100){ 
                        break;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        for(int i = 0; i < n; i++){
            new Test4(i).start();
        }
    }
}

你可能感兴趣的:(后端,经验分享,面试,java)