超级实习生计划学习打卡—Java 多线程 线程8锁(含示例代码)

1.标准访问 

class Phone{
    public synchronized void sendEmail() throws Exception {
        System.out.println("**sendEmail");
    }
    public synchronized void sendSMS() throws Exception {
        System.out.println("**sendSMS");
    }
}
public class Lock8Demo {
    public static void main(String[] args) throws InterruptedException {
        Phone phone=new Phone();
        new Thread(()->{
            try{
                phone.sendEmail();
            }catch (Exception e){
                e.printStackTrace();
            }
        },"A").start();
        new Thread(()->{
            try{
                phone.sendSMS();
            }catch (Exception e){
                e.printStackTrace();
            }
        },"B").start();
    }
}

两个方法均使用synchronized关键字修饰,A、B两线程互斥。线程的执行顺序,是根据cpu的分配情况,而不是根据代码的先后次序,因此打印结果是1,2或者2,1不确定。

2.线程休眠

对sendEmail()方法进行如下修改:

public synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("**sendEmail");
    }

一个对象只有一把锁,当一个线程获取了该对象的锁之后,其他线程无法获取该对象的锁,所以无法访问该对象的其他synchronized实例方法。(先到先得)

A、B线程执行的先后顺序依然是不确定的,因此打印结果是1,2或者2,1不确定。

3.新增普通方法
在Phone类中新增普通“sayHellow”方法:

public void sayHellow() throws Exception {
        System.out.println("**sayHellow");
    }

修改线程B中调用的方法

phone.sayHellow();
//phone.sendSMS();

因为普通方法与同步方法没有冲突,所以“sayHellow”先被打印(此时A线程被暂停)

4.两个对象调用两个线程

将线程C注释掉,再新建一个对象:

Phone phone1=new Phone();

修改线程B中调用sendSMS()方法及对象:

//phone.sayHellow();
//phone.sendSMS();
phone1.sendSMS();

每个对象都有一个对象锁,不同的对象,他们的锁不会互相影响。

所以两线程并行执行,“sendSMS”先被打印。

5.一个对象调用两个静态同步方法

在两个同步方法前加修饰词static:

 public static synchronized void sendEmail() throws Exception
 public static synchronized void sendSMS() throws Exception

修改线程B中调用sendSMS()方法的对象:

phone.sendSMS();
//phone1.sendSMS();

同1理,打印结果是1,2或者2,1不确定。

6.两个对象调用两个静态同步方法

修改线程B中调用sendSMS()方法的对象:

//phone.sendSMS();
phone1.sendSMS();

当synchronized作用于静态方法时,其锁就是当前类的class锁,不属于某个对象。

虽然对象不同,但属于同一个类,线程仍需要等待上一个对象结束线程,释放锁以后,才能进行。

由于A、B线程执行的先后顺序依然是不确定的,因此打印结果是1,2或者2,1不确定。

7.一个对象调用一个静态同步方法和一个普通同步方法


去掉sendSMS()同步方法中的修饰词static,并修改线程B中调用sendSMS()方法的对象:
 

phone.sendSMS();
//phone1.sendSMS();

8.两个对象调用一个静态同步方法和一个普通同步方法

修改线程B中调用sendSMS()方法的对象:

//phone.sendSMS();
phone1.sendSMS();

同7理,两线程并行执行,“sendSMS”先被打印。

补充:
synchronized实现同步的基础:Java中每一个对象都可以作为锁。

具体表现为以下3种形式:

①对于普通同步方法,锁是当前实例对象;

②对于同步方法块,锁是synchronized括号里配置的对象;

③对于静态同步方法,锁是当前类的class对象;
 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是微信小程序制作学习计划打卡代码示例: 1. 在小程序的页面中添加一个表单,包括计划名称、学习时长、完成情况等字段。 ```html <form bindsubmit="formSubmit"> <label>计划名称</label> <input type="text" name="planName" placeholder="请输入计划名称"> <label>学习时长</label> <input type="text" name="studyTime" placeholder="请输入学习时长"> <label>完成情况</label> <select name="isFinished"> <option value="0">未完成</option> <option value="1">已完成</option> </select> <button type="submit">提交打卡</button> </form> ``` 2. 在小程序的 js 文件中添加表单提交的事件处理函数,将用户输入的数据发送到服务器保存。 ```javascript Page({ formSubmit: function(e) { wx.request({ url: 'https://api.example.com/plan/daka', method: 'POST', data: e.detail.value, success: function(res) { console.log(res.data) // 提交成功后跳转到打卡记录列表页 wx.navigateTo({ url: '/pages/record/list' }) } }) } }) ``` 3. 在服务器端编写接收表单数据的 API,并保存到数据库中。 ```javascript const express = require('express') const bodyParser = require('body-parser') const app = express() app.use(bodyParser.json()) app.post('/plan/daka', (req, res) => { const planName = req.body.planName const studyTime = req.body.studyTime const isFinished = req.body.isFinished // 将数据保存到数据库中 // ... res.json({ success: true }) }) app.listen(3000, () => { console.log('Server is running on port 3000') }) ``` 以上是一个简单的微信小程序制作学习计划打卡示例,具体实现方式可以根据自己的需求进行调整和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值