zoukankan      html  css  js  c++  java
  • synchronized 读写同步

    synchronized 读写同步

    这是一道面试题,很多人也遇到了。

    要求:1.读-读 不用线程同步。2.读-写 要求线程同步,写的时候不能读。3.写-写同步。写的时候不能写。

    java lock读写锁是好的处理方案。这里不说了。但人家问的是synchronized 读写同步。

    假设两个方法,write() ,read();
    1. read()之间不需要同步,正常的就行。
    2. read()与write()之间需要同步。
    3. write()之间需要同步。
    1.和3.很好理解也很现实。

    经过思考:write()必须是同步的,所有对象都要同步。那这里需要设计成静态的。如果不静态的,保证每次同步都是一个锁。
    其次 read() 之前要栓查write同步锁,但又没有对应方法可以检查。想到的是 再写一个栓查方法。这个方法与write使用同一个同步锁(设计在同一个类,同时静态)。但这个方法是空的,什么也不做。
    所以设计成如下代码:
    package test;
    
    public class Test {
    
        public void read() {
    
            canRead();
            System.out.println(Thread.currentThread().getName() + "-->>begain read");
            System.out.println(Thread.currentThread().getName() + "-->>reading");
            try {
                Thread.sleep(1100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "-->>read end");
        }
    
        public static synchronized void canRead() {
    
        }
    
        public static synchronized void write() {
            System.out.println(Thread.currentThread().getName() + "-->>begain write");
            canRead();
            System.out.println(Thread.currentThread().getName() + "-->>writing");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "-->>writing end");
            return;
        }
    
        public static void main(String[] args) {
    
            Test test = new Test();
            Thread t = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true) {
                        test.read();
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            t.setName("read_thread_1");
            t.start();
    
            Thread t1 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true) {
                        test.read();
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            t1.setName("read_thread_2");
            t1.start();
    
            Thread t2 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Test.write();
                    }
                }
            });
            t2.setName("write_thread");
            t2.start();
            Thread t3 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Test.write();
                    }
                }
            });
            t3.setName("write_thread_2");
            t3.start();
    
        }
    
    }

    运行结果如下,通过结果分析,读线程是穿插的,不存在同步。写线程都是完整执行过程,是同步的。

    read_thread_1-->>begain read

    read_thread_1-->>reading

    read_thread_2-->>begain read

    read_thread_2-->>reading

    read_thread_1-->>read end

    read_thread_2-->>read end

    read_thread_1-->>begain read

    read_thread_1-->>reading

    read_thread_2-->>begain read

    read_thread_2-->>reading

    read_thread_1-->>read end

    read_thread_2-->>read end

    write_thread-->>begain write

    write_thread-->>writing

    write_thread-->>writing end

    read_thread_2-->>begain read

    read_thread_2-->>reading

    read_thread_1-->>begain read

    read_thread_1-->>reading

    write_thread_2-->>begain write

    write_thread_2-->>writing

    write_thread_2-->>writing end

    read_thread_2-->>read end

    read_thread_1-->>read end

    read_thread_2-->>begain read

    read_thread_2-->>reading

    read_thread_1-->>begain read

    read_thread_1-->>reading

    read_thread_2-->>read end

    read_thread_1-->>read end

    write_thread-->>begain write

    write_thread-->>writing

    write_thread-->>writing end

    write_thread_2-->>begain write

    write_thread_2-->>writing

    write_thread_2-->>writing end

    read_thread_1-->>begain read

    read_thread_1-->>reading

    read_thread_2-->>begain read

    read_thread_2-->>reading

    read_thread_1-->>read end

    read_thread_2-->>read end

    read_thread_1-->>begain read

    read_thread_1-->>reading

    read_thread_2-->>begain read

    read_thread_2-->>reading

    write_thread-->>begain write

    write_thread-->>writing

    read_thread_1-->>read end

    read_thread_2-->>read end

    write_thread-->>writing end

    write_thread_2-->>begain write

    write_thread_2-->>writing

    write_thread_2-->>writing end

    read_thread_2-->>begain read

    read_thread_2-->>reading

    read_thread_1-->>begain read

    read_thread_1-->>reading

    read_thread_2-->>read end

    read_thread_1-->>read end

    read_thread_2-->>begain read

    read_thread_1-->>begain read

    read_thread_1-->>reading

    read_thread_2-->>reading

    write_thread-->>begain write

    write_thread-->>writing

    这个代码冗余部分是要执行一个空方法,目前还没有想到其它方法,有大牛有好办法可以留言互相学习。

    代码 bug :开始写的时候还没有读完的线程。会导致错误。

    -----待改进-----------

  • 相关阅读:
    一个别人的心得(转发的)
    常见的游戏设计技术
    查看更新
    xml,json和各种序列化工具的对比
    python游戏环境搭建
    快速制作游戏
    子网和掩码
    nat
    pycharm使用技巧
    IP的面向无连接状态
  • 原文地址:https://www.cnblogs.com/mamamia/p/8006643.html
Copyright © 2011-2022 走看看