zoukankan      html  css  js  c++  java
  • 记录一次回客科技有关线程的笔试题,三个线程加法和一个线程减法 ,延申的两个线程交替执行

    今天去了回客科技 笔试了一波。很遗憾啊,脑袋有思路 但是还没到手写代码很熟练的程度,基本功不到位。

    第一道:线程的题:三个线程 +1 一个线程 -1 运算 。

    看到网上还有四个线程的,两个加法计算,两个减法运算。基本的思路都是一样的 ,注意看同步处理。

    下面贴出代码实现:

    public class AddTest {
    
        private static int i;
    
        private static Object object = new Object();
    
        public static void main(String[] args) {
            
        
            new Thread(() -> {
                synchronized (object) {
                    i++;
                }
            }).start();
    
            new Thread(() -> {
                synchronized (object) {
                    i++;
                }
    
            }).start();
    
            new Thread(() -> {
                synchronized (object) {
                    i++;
                }
            }).start();
    
            new Thread(() -> {
                synchronized (object) {
                    i--;
                }
            }).start();
    //这里睡眠 等所有线程运行完毕 看最终的数值,2
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i);
    
        }
    }
    这里引申出来了其他问题的思考
    第1种:
    synchronized void add 修饰普通方法 等同于  
    synchronized (this)
     public int i = 0;
    
        public void add(String threadName) {
            synchronized (this) {
                i++;
                System.out.println(threadName + "加法运算:" + i);
            }
        }
    
    //上面代码等于如下代码:
    
       public synchronized void add(String threadName) {
      
                i++;
                System.out.println(threadName + "加法运算:" + i);
          
        }
    第2种:
    synchronized static void add 修饰静态方法 等同于
    synchronized (*.class)
    说明:以上两种我分析为 synchornized 修饰普通方法和this 对应的是同一个实例对象。
    而修饰静态方法和class 是对应的同一个类的 唯一的class对象。
    这个是我的理解,有错误之处请各位指正。

    第二道:
    一个线程加一运算,一个线程做减法运算,多个线程同时交替运行(延申的)第1种方法:使用Synchronized 实现


    public class Count {
        private int num = 0;
        private boolean flag = false; // 标识
    
        //加法
        public synchronized void add() {
            while (flag) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.num++; //
            System.out.println(Thread.currentThread().getName() + "........" + this.num);
            this.flag = true; //设置标识为true
            notifyAll(); //唤醒所有在线程池中冻结的线程,会把所有都唤醒
    
        }
    
        //减法
        public synchronized void sub() {
            while (!flag) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.num--; //
            System.out.println(Thread.currentThread().getName() + "........" + this.num);
            this.flag = false; //设置标识为true
            notifyAll(); //唤醒所有在线程池中冻结的线程,会把所有都唤醒
        }
    }
    
    
    


     第2种 :使用Lock 锁实现
     
    public class CountLock {
    
        private int num = 0;
        private boolean flag = false; // 标识
        Lock lock = new ReentrantLock(); //
        Condition add = lock.newCondition(); // 加法锁
        Condition sub = lock.newCondition();// 减法锁
    
        public void add() {
            lock.lock();// 锁上
            try {
                while (flag) {  //循环判断
    
                    add.await();
                }
                this.num++;
                System.out.println(Thread.currentThread().getName() + "........" + this.num);
                this.flag = true; // 设置标识
                sub.signal(); // 唤醒指定线程
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void sub() {
            lock.lock();// 锁上
            try {
                while (!flag) {//循环判断
                    sub.await();
                }
                this.num--;
                System.out.println(Thread.currentThread().getName() + "........" + this.num);
                this.flag = false; // 设置标识
                add.signal(); // 唤醒指定线程
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    调用的 main 方法

    public static void main(String[] args) {
            //Count c=new Count();
            CountLock c=new CountLock();
    
            Thread t1=new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        c.add();
                    }
                }
            });
            Thread t2=new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true){
                        c.sub();
                    }
    
                }
            });
    
            t1.start();
            t2.start();
       //这里感觉线程少可以再启动 两个t3或者t4 来验证真实性
    
        }
    
    

    这里延申的知识点参考博客:

    一个线程加一运算,一个线程做减一运算,多个线程同时交替运行--synchronized

    java synchronized修饰普通方法,修饰静态方法,修饰代码块,修饰线程run方法 比较

    
    
  • 相关阅读:
    二维图像的DCT变换
    Shell脚本加密--shc/gzexe
    vim python插件--vim python mode
    移动端图片裁剪解决方案
    移动端压缩并ajax上传图片解决方案
    html5拖拽实现
    html5的触摸事件
    js循环添加事件的问题
    h5上传图片
    thinkphp加载第三方类库
  • 原文地址:https://www.cnblogs.com/liran123/p/9393153.html
Copyright © 2011-2022 走看看