两个线程 交替打印0-100 synchronized、Lock、volatile

 看到一个面试题交替打印0-100,本来想着应该挺简单的,复制一下看看,然后在csdn找了一些博客,尝试了好几个博客的代码,最后导致线程输出到99就卡在那,不能正常结束,居然没一个发现问题,我都服气了。

csdn博客质量,抄的人都不带脑子抄,我就没发现一个正常的。

假设打印0-99,交替打印使用synchronized的时候,A线程: i到99时输出,然后i+1 =100,A线程会调用wait 阻塞进入等待队列。这时B线程发现i=100了直接跳出循环了,就不会去循环里面执行notify唤醒了。导致A线程阻塞在那。。。主线程也搁那一直等。 

wait,notify


//synchronized
public class mutil_print_sync {
    static int i=0;
    static Object lock=new Object();
    static class ThreadA implements Runnable {
        @Override
        public void run() {
            synchronized (lock){
                while(i<100){
                    lock.notify();
                    if(i%2==1){
                        System.out.println("A"+i);
                        i++;
                    }
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }//end while
                lock.notify();
    //必须执行唤醒 不然线程会卡在99 wait,而另一个线程已经到100不执行循环,没有唤醒操作了,导致不能结束
            }

        }
    }

    static class ThreadB implements Runnable {
        @Override
        public void run() {
            synchronized (lock){
                while (i<100){
                    lock.notify();
                    if(i%2==0){
                        System.out.println("B:"+i);
                        i++;
                    }
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //end while
                lock.notify();//必须执行唤醒 不然线程会卡在99 wait,而另一个线程已经到100不执行循环,没有唤醒操作了
            }

        }
    }
    
    public static void main(String[] args) {
        new Thread(new ThreadA()).start();
        new Thread(new ThreadB()).start();
    }

}

 使用Lock的方法,lock,unlock方法



import java.util.concurrent.locks.ReentrantLock;

public class mutil_print_lock {

    public static ReentrantLock lock=new ReentrantLock();
    public static int i=0;
    static class ThreadA extends Thread{
        @Override
        public void run() {
            while(i<100){
                lock.lock();
                if (i < 100) {
                    if(i%2==1){
                        System.out.println("A"+i);
                        i++;
                    }
                }
                lock.unlock();
            }

        }
    }

    static class ThreadB extends Thread{
        @Override
        public void run() {
            while(i<100){
                lock.lock();
                if (i < 100) {
                    if(i%2==0){
                        System.out.println("B"+i);
                        i++;
                    }
                }
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        new ThreadA().start();
        new ThreadB().start();
    }
}

信号量机制


public class mutil_print_volatile {
    public static volatile int i=0;
    static class ThreadA extends Thread{
        @Override
        public void run() {
            while(i<100){
                if (i < 100) {
                    if(i%2==1){
                        System.out.println("A"+i);
                        i++;
                    }
                }
            }

        }
    }

    static class ThreadB extends Thread{
        @Override
        public void run() {
            while(i<100){
                if (i < 100) {
                    if(i%2==0){
                        System.out.println("B"+i);
                        i++;
                    }
                }
            }
        }
    }
    public static void main(String[] args) {
        new mutil_print_lock.ThreadA().start();
        new mutil_print_lock.ThreadB().start();
    }
}


版权声明:本文为shenkunchang1877原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。