Java 锁之wait()与notify()

在编写简单的聊天室时,需要线程间的通信。

服务器与客户端之间是通过线程连接到一块的,他们都需要最基础的通信层,我是用Communication类来表示。

Communication需要完成最基本的通信信道的建立。客户端与服务器除了最基本的通信层之外还需要客户端会话层(ClientConversation)与服务器会话层(ServerConversation),服务器层(Server)与客户端层(Client)并不能直接进行通信。

完成Communication类时需要用到线程,要实现Runnable接口,则需要完成相关的Run() 方法。在Communication类构造方法中执行以下代码:

try {
    lock = new Object();
    this.socket = socket;
    this.dis = new DataInputStream(socket.getInputStream());
    this.dos = new DataOutputStream(socket.getOutputStream());
    synchronized (lock) {
        this.goon = true;
        new Thread(this, "侦听对端消息线程").start();   // 开启新的线程
	
    /* 如果开启线程后还有其他代码要处理,则,它们一定在子线程真正运行之前执行,应该将代码放在wait() 方法与new Thread 之间。*/
        try {
          lock.wait();
        } catch (InterruptedException e) {
	    e.printStackTrace();
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}

new Thread().start() 之后就开启一个新的线程。


@Override
public void run() {
    String message = "";
    synchronized (lock) {
	lock.notify();
    }
		
    while (goon) {
	try {
		message = dis.readUTF();
		dealNetMessage(new NetMessage(message));  // 处理对端消息 抽象方法,在Conversation层实现
	} catch (IOException e) {
		if (goon == true) {
		    goon = false;
		    peerAbnormalDrop();    // 处理对端异常掉线 抽象方法,在Conversation层实现
	        }
        }
    }
    close(); // 关闭线程
}

        当运行到new Thread().start(),新线程开启,但是为了防止start() 之后还有其他代码还未执行,但是新开启的线程已经执行完,所以给相关方法加锁,加锁后,其他线程只能在就绪态等待,就避免了上述情况,等锁打开时新的线程与其他线程一块竞争CPU,此时用wait()、notify()对相关代码进行操控。

wait()方法,在阻塞自身线程前,必然开lock锁;当该线程被其它线程notify()后,将再次进入lock锁块,而进一步对lock上锁。

要注意:线程被wait()之后只能通过notify()来唤醒。并且它们只能在相应的synchronized(){}语句块内执行。

        之前在编写程序时,很少考虑到用锁的问题,也没有考虑到线程并发的问题,教主用了几乎两个小时的时间讲了关于锁和wait()、notify(),才发现线程安全问题真的很重要,我现在对锁的理解还不够深刻,写出来的博文还是很肤浅。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值