挂面10

作者: 盼旺 | 来源:发表于2019-11-05 08:57 被阅读0次

1.Java多线程中的竞争条件概念

Java中的多线程,当多个线程对一个数据进行操作时,可能会产生“竞争条件”的现象,这时候需要对线程的操作进行加锁,来解决多线程操作一个数据时可能产生问题。加锁方式有两种,一个是申明Lock对象来对语句快进行加锁,另一种是通过synchronized 关键字来对方法进行加锁。以上两种方法都可以有效解决Java多线程中存在的竞争条件的问题。

2.wait(),notify(),notifyAll()

首先,调用一个Object的wait与notify/notifyAll的时候,必须保证调用代码对该Object是同步的,也就是说必须在作用等同于synchronized(obj){......}的内部才能够去调用obj的wait与notify/notifyAll三个方法,否则就会报错

  • wait()
    调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。wait()总是在一个循环中被调用,挂起当前线程来等待一个条件的成立。 Wait调用会一直等到其他线程调用notifyAll()时才返回。
  • notify()
    调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。
  • notifyAll()
    唤醒上面所有等待的线程

5.谈一下synchronized和wait()、notify()等的关系

1.有synchronized的地方不一定有wait,notify
2.有wait,notify的地方必有synchronized.这是因为wait和notify不是属于线程类,而是每一个对象都具有的方法,而且,这两个方法都和对象锁有关,有锁的地方,必有synchronized。
3.如果要把notify和wait方法放在一起用的话,必须先调用notify后调用wait,因为如果调用完wait,该线程就已经不是当前线程了。所以它得先提醒别人我准备释放锁了

4.Java实现阻塞队列

public class BlockingQueue {
    private List queue = new LinkedList();
    private int limit = 10;
    public BlockingQueue(int limit){
        this.limit=limit;
    }
    public  synchronized void enqueue(Object item) throws InterruptedException{
        while (this.queue.size()==this.limit){
            wait();
        }
        if(this.queue.size()==0){
            notifyAll();
        }
        this.queue.add(item);
    }
    public synchronized Object dequeue() throws InterruptedException{
        while (this.queue.size()==0){
            wait();
        }
        if(this.queue.size()==this.limit){
            notifyAll();
        }
        return this.queue.remove(0);
    }
}

在enqueue和dequeue方法内部,只有队列的大小等于上限(limit)或者下限(0)时,才调用notifyAll方法。如果队列的大小既不等于上限,也不等于下限,任何线程调用enqueue或者dequeue方法时,都不会阻塞,都能够正常的往队列中添加或者移除元素。

5.Java 多线程中两个线程交替执行,一个输出偶数,一个输出奇数

java8方法引用有四种形式:
静态方法引用       :   ClassName :: staticMethodName
构造器引用        :   ClassName :: new
类的任意对象的实例方法引用:   ClassName :: instanceMethodName
特定对象的实例方法引用  :   object :: instanceMethodName

1.利用synchronized  notify() wait()
public class ThreadPrintDemo2 {
    public static void main(String[] args) {
        final ThreadPrintDemo2 demo2 = new ThreadPrintDemo2();
        Thread t1 = new Thread(demo2::print1);
        Thread t2 = new Thread(demo2::print2);

        t1.start();
        t2.start();
    }

    public synchronized void print2() {
        for (int i = 1; i <= 100; i += 2) {
            System.out.println(i);
            this.notify();//先提醒别人,我准备释放锁了
            try {
                this.wait();
                Thread.sleep(100);// 防止打印速度过快导致混乱
            } catch (InterruptedException e) {
                // NO
            }
        }
    }

    public synchronized void print1() {
        for (int i = 0; i <= 100; i += 2) {
            System.out.println(i);
            this.notify();
            try {
                this.wait();
                Thread.sleep(100);// 防止打印速度过快导致混乱
            } catch (InterruptedException e) {
                // NO
            }
        }
    }
}

使用 volatile

public class ThreadPrintDemo2 {
    static volatile int num = 0;
    static volatile boolean flag = false;
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            for (; num<100; ) {
                if (!flag && (num == 0 || num % 2 == 0)) {
                    num++;
                    try {
                        Thread.sleep(100);// 防止打印速度过快导致混乱
                    } catch (InterruptedException e) {
                        //NO
                    }

                    System.out.println(num);
                    flag = true;
                }
            }
        }
        );

        Thread t2 = new Thread(() -> {
            for (; num<100;) {
                if (flag && (num% 2 != 0)) {
                    num++;
                    try {
                        Thread.sleep(100);// 防止打印速度过快导致混乱
                    } catch (InterruptedException e) {
                        //NO
                    }

                    System.out.println(num);
                    flag = false;
                }
            }
        }
        );
        t1.start();
        t2.start();
    }
}
num++ 不是原子的,但不妨碍,因为有 flag 变量控制。
而 num 必须是 volatile 的,如果不是,会导致可见性问题。

6.java中什么叫原子操作?

就是无法被别的线程打断的操作。要么不执行,要么就执行成功。
例如:
x=3是原子操作。过程就是先把工作内存的x赋成3,再把主存的x赋成3。
y=x不是原 子操作,它涉及在工作内存先把x值读出来,再把这个值赋给y。
x++x=x+1也不是原子操作,它涉及取值,自加和赋值。

7.mybatis的接口和xml交互,用到了代理了吗?

用到了JAVA动态代理
注册:将 Mapper.xml 中的节点信息和 Mapper 类中的注解信息与 Mapper 类的方法一一对应,每个方法对应生成一个 MapperStatement,并添加到 Configuration 中;
绑定:根据 Mapper.xml 中的 namespace 生成一个 Mapper.class 对象,并与一个 MapperProxyFactory 代理工厂对应,用于 Mapper 代理对象的生成。

相关文章

  • 挂面10

    1.Java多线程中的竞争条件概念 Java中的多线程,当多个线程对一个数据进行操作时,可能会产生“竞争条件”的现...

  • 超市买挂面,一定要看清一个字!吃了这么多年,居然今天才明白!

    鸡蛋挂面、杂粮挂面、营养素强化挂面…… 超市中的挂面品种还真不少 工作忙或是偶尔想偷懒的你 可能家里也会储备点挂面...

  • 挂面

    挂面是以小麦粉添加盐、碱、水经悬挂干燥后切制成一定长度的干面条。挂面始于元代,到建国前大部分都是手工制作,靠太阳晒...

  • 挂面

    材料: 挂面、酱油、老干妈、郫县豆瓣、香油,如果有点牛肉干甚佳。 烹调方法: 酱油铺满碗底,老干妈一小匙,一小筷(...

  • 挂面

    看着餐桌上冒着热气的挂面 一撮葱花, 半匙辣椒, 如你习惯的调料 如你喜欢的味道 我一条一条的吮吸 聊表挂念

  • 挂面

    和往常一般,煮了碗挂面 安在了你的位置 冒着热气 一撮葱花,半匙辣椒 如你习惯的调料, 如你喜欢的味道 聊表挂念,...

  • 挂面

    我应该是三年级开始独居的,爸妈姐姐们都在外,或赚钱去或上学去,总是一个偌大的院子,只有我一个人,不论白天黑夜,只有...

  • 挂面

    挂面早打唐代就开始有了。当时被叫做“须面”,被装入礼盒,馈赠亲朋,也有人家用作儿女婚嫁的聘礼。北方的饮食中,面类不...

  • 挂面!

    接上文 我就猜到那个朋友打王者去了,所以没看到我的消息,三十几分钟之后,我借到了锅哈哈哈! 借热水,插插头,煮面,...

  • 挂面

    今天收到了在网上买的挂面,挂面像银丝般细细的。 挂面本身就有盐味,我用清水煮了一碗,下了一些青菜和香菜,没有放油,...

网友评论

      本文标题:挂面10

      本文链接:https://www.haomeiwen.com/subject/zulwmctx.html