多线程顺序打印1-50

前言

面试被问到这个了,没写出来诶,上课真的没讲过一点多线程的知识,项目也没接触过(是我菜了)

基础知识

  • 线程基础知识
    • java多线程的底层实现
    • 线程的创建、启动、生命周期
  • 锁的基本知识
    • 锁的类别
    • 锁的基本使用
    • synchronized基本使用

代码

synchronized关键字版本

class KeywordThread implements Runnable {
    private int num = 1;
    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                notifyAll();
                if (num <= 50) {
                    System.out.println(Thread.currentThread().getName() + " : " + num);
                    num++;
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    break;
                }
            }
        }
    }
}

lock版本

class LockThread implements Runnable {
    private int num = 1;
    private Lock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            if (num > 50) {
                break;
            }
            lock.lock();
            if (check()) {
                if (num <= 50) {
                    System.out.println(Thread.currentThread().getName() + " : " + num);
                    num++;
                }
            }
            lock.unlock();
        }
    }

    //这里通过线程名字来控制了,也可以通过其他方式
    private boolean check() {
        String name = Thread.currentThread().getName();
        int th = name.charAt(name.length() - 1) - '0';
        return num % 3 == th;
    }
}

这个版本同时控制了打印的顺序

注意break的时机,不要把unlock给break掉了,并且不要使用stop方法,要让run语句执行完线程就自动结束了。

启动

public static void main(String[] args) {
    LockThread thread = new LockThread();
    //KeywordThread thread =` new KeywordThread();
    new Thread(thread, "thread1").start();
    new Thread(thread, "thread2").start();
    new Thread(thread, "thread0").start();
}

另类:使用Thread版本

创建继承Thread的线程类

class StaticThread extends Thread {
    //使用两个static变量,同时obj使用final
    private static int num = 1;
    private static final Object obj = new Object();
    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                obj.notifyAll();
                if (num <= 50) {
                    System.out.println(Thread.currentThread().getName() + " : " + num);
                    num++;
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    break;
                }
            }
        }
    }
}

启动

public static void main(String[] args) {
        StaticThread thread1 = new StaticThread();
        StaticThread thread2 = new StaticThread();
        StaticThread thread3 = new StaticThread();
    //继承自Thread,所以可以直接启动
        thread1.start();
        thread2.start();
        thread3.start();
    }

实际上这种情况是弱化了Thread作用,下转型成为Runnable了,这种形式不推荐,但是可以对这道题理解透彻。

谈谈作用

锁作为数据库、操作系统的重要知识,是我们必须掌握的,后来的分布式锁会有广泛作用。问这道题也是想探一下我们的基础,要求我们在开发的时候能想到,不用锁之后并发导致数据不一致的种种问题。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注