java多线程同步 - 实现打印出[0,100]间的整数,主线程打印偶数,子线程打印奇数

方式1:使用synchronized(object) 和 while循环

缺点:有太多的无效抢锁操作,导致程序效率非常低

代码示例如下:

public class Main {
    public static int i=0;
    public static Object syncObject=new Object();
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(i < 100) {
                    //这里有可能前一个循环结束放锁有,又是本线程抢到锁,空循环一次,因此本方法效率很低
                    synchronized (syncObject) {
                        if (i % 2 != 0) {
                            System.out.println(i++ + "奇数线程子");
                        }
                    }
                }
            }
        }).start();
        while(i < 100) {
            //这里有可能前一个循环结束放锁有,又是本线程抢到锁,空循环一次,因此本方法效率很低
            synchronized (syncObject) {
                if (i % 2 == 0) {
                    System.out.println(i++ + "偶数线程主");
                }
            }
        }
    }
}

方式2:使用Object类的 wait()、notify()、notifyAll() 等函数

缺点:线程初始化的时候,为了让主线程的代码先执行,需要有一个死循环+sleep(100)的操作,这个最好能够去掉

public class Main {
    public static int i = 0;
    public static boolean bFlag=false;
    public static Object syncObject = new Object();
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //这加段代码,判断主线程的while运行完一次再运行本子线程后面的代码
                    while(!bFlag){
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    while (i <= 100) {
                        synchronized (syncObject) {
                            //主线程执行到这里,可以保证子线程已经执行了一次printline且开始阻塞等待唤醒了
                            System.out.println(i++ + "奇数线程子");
                            syncObject.notify();
                            syncObject.wait();
                        }
                    }
                    synchronized (syncObject) {
                        syncObject.notifyAll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        try {
            //要保证本线程的本代码比打印奇数的线程代码先执行
            while (i <= 100) {
                synchronized (syncObject) {
                    bFlag=true;
                    System.out.println(i++ + "偶数线程主");
                    syncObject.notify();
                    syncObject.wait();
                }
            }
            synchronized (syncObject) {
                syncObject.notifyAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/hemeinvyiqiluoben/article/details/82984594