java 多线程 synchronized与Object类中wait、notify、notifyAll方法的使用

synchronized的使用:

(1)synchronized(obj){}的使用

obj是一个实例对象,可以是任意对象,当在多线程中通过各种方式执行到该synchronized包围的代码段,需要先拿到obj对象的锁才能继续往后执行,否则就阻塞,阻塞的时候一直判断有没有拿到obj的锁,如果拿到obj的锁了,就可以继续执行,如果还没拿到obj的锁,继续阻塞。

(2)synchronized用在实例方法(或者叫做动态方法)上

相当于(1)中所说的

synchronized(this){

     //实例方法的代码放在这...

}

(3)synchronized用在静态方法上

假设该静态方法属于A类,则相当于(1)中所说的

 

synchronized(A.class){

     静态方法的代码放在这...

}

Object中wait、notify、notifyAll方法的使用

正常使用这三个方法的前提:这三个方法的使用必须在同步代码块中,并且该同步代码块的对象锁是这几个方法所属的对象的对象锁。否则报非法监视器异常(IllegalMonitorStateException)。具体看下面代码:

//下面synchronized的参数如果是lock对象,则在该同步代码块内只能调用lock对象的wait、notify、notifyAll方法
        synchronized (lock) {
            try {
                lock.wait();
                // lock.notify();
                // lock.notifyAll();
            } catch (InterruptedException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }

为什么要这样呢?因为释放锁与获得的锁都要是同一个锁才能保证同步。

synchronized一开始是获得lock对象的锁,那么只有调用lock对象的wait方法才能保证这个时候wait方法释放的是同一把锁。

用反例来说明:

首先,wait方法的作用是释放对象锁,然后阻塞当前线程(也就是当前线程跑到阻塞队列中了)。

当调用的是其他对象的wait方法时,不会释放lock的对象锁,而当前线程却又跑到阻塞队列中了,那么lock对象锁还是一直被当前线程把持着----------也就是说,当前线程被阻塞了,却还持有lock的对象锁,这就会导致其它线程无法再获得lock的对象锁,然后导致死锁。

1、wait的使用

   前面的例子中其实就是用wait作为讲解,这里不再赘述。

2.notify的使用

唤醒该notify()方法所属对象的等待集中随机一个线程,被唤醒的线程处于可运行状态,即此时该线程可以和其他线程一起竞争锁了。

但是,需要注意,调用notify时,所属同步代码块是不会立即释放锁的,而是在该代码块执行完之后释放锁,也就是说,被唤醒的线程还是要等当前调用notify的线程中的同步代码块执行完才能开始竞争,否则只能等着。不懂的话,看下面的截图

3.notifyAll的使用

与notify类似,只不过是唤醒该notifyAll方法所属对象的等待集中的所有线程,其他就与notify一样了。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用MATLAB代码实现导入Excel点名并使用GUI界面的步骤: 1. 创建GUI界面:使用MATLABGUIDE工具创建GUI界面,包括按钮、文本框、列表框等控件,以及相关的回调函数。 2. 导入Excel数据:使用MATLAB的xlsread函数读取Excel的点名数据,并将其存储为MATLAB的数组。 3. 显示点名信息:在GUI界面的列表框显示点名信息。 4. 实现点名功能:在GUI界面添加“点名”按钮,并编写相应的回调函数。回调函数实现随机选取一个学生的功能,并将其在GUI界面显示出来。 下面是一个简单的示例代码,可以供参考: ``` function mygui % 创建GUI界面 fig = figure('Position',[300,300,300,200],'MenuBar','none','ToolBar','none'); nameListbox = uicontrol('Style','listbox','Position',[20,20,120,160]); randNameText = uicontrol('Style','text','Position',[160,100,120,20],'String','随机点名:'); randNameEdit = uicontrol('Style','edit','Position',[160,70,120,20],'String',''); randNameButton = uicontrol('Style','pushbutton','Position',[160,20,120,40],'String','点名','Callback',@randNameButtonCallback); % 导入Excel数据 [num,txt,raw] = xlsread('点名表.xlsx'); % 显示点名信息 set(nameListbox,'String',txt(2:end)); % 实现点名功能 function randNameButtonCallback(source,event) randIndex = randi(size(txt,1)-1); randName = txt{randIndex+1}; set(randNameEdit,'String',randName); end end ``` 注意:在使用该代码时,需要将Excel文件名修改为实际的文件名,并确保Excel文件的点名数据位于第二行及以后的行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值