Java多线程实战编程-----活例分析

Java多线程实战编程-----活例分析

以下给出一个 CS小框架底层的Communication类的实现,牵扯到 多线程的安全性问题
communication 可以为上层的conversation所用,里面创建了一个线程,这个线程用来侦听对端发过来的消息,而communication是被一个线程调用的,暂且称为主线程。 创建的侦听线程称为子线程。
我们要实现的是让 Communication的构造方法完成前 ,一定要让侦听线程 运行起来。
我们采取加锁的方法,接下来看看具体实现。

public abstract class Communication implements Runnable {
	private Socket socket;
	private DataInputStream dis;
	private DataOutputStream dos;
	private volatile boolean goon;
	private Object lock;
	
	Communication(Socket socket) {
		try {
			this.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, "COMMUNICATION").start();
				// 如果这里也存在代码,则,它们可能在子线程真正运行之前执行。
				try {
					lock.wait();
					// wait()方法,在阻塞自身线程前,必然开lock锁;
					// 当该线程被其它线程notify()后,将再次进入lock锁块
					//而进一步对lock上锁。
				} catch (InterruptedException e) {
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void run() {
		String message = null;
		synchronized (lock) {
			lock.notify();
		}
		
		while (goon) {
			try {
				message = dis.readUTF();
				dealNetMessage(new NetMessage(message));
			} catch (IOException e) {
				if (goon == true) {
					goon = false;
					peerAbnormalDrop();
				}
			}
		}
		close();
	}

  1. 初态,对象锁lock的开着的,主线程先进入到里面,然后将锁关闭,
    当执行到第16行的时候,执行start()函数,这时子线程 进入就绪态,这时候就有两个线程,共同竞争CPU。

  2. 第一种情况 主线程时间片段用完,则执行子线程 进入run()方法,但是 33行 对象锁是关着的
    (两个线程公用一把锁)故一直等待 直至时间片段耗完,而后进主线程到达17行,执行相关代码
    第二种情况 主线程自己继续往下运行。

    这两种情况 都能够到底下这种情况

    到了第19行,利用wait方法将自己阻塞,而将对象锁打开
    这时候,就可以执行 子线程,子线程的锁刚好也是开着的,进去之后将锁关闭,并且唤醒 主线程,
    使其进入就绪态
    1.这时候 如果子线程时间片段到了,就进入主线程,而主线程,锁还是锁着的,
    就又回到子线程,子线程,出锁之后,并执行 底下的read()
    2. 若时间片段没有到的话,也就继续执行read()

这样就基本上实现了 Communication 构造方法运行结束前,侦听线程启动起来。

有的童鞋会说,可以将read()包含到锁里面,
那么这样会有什么问题呢?
注意: read( )也是一个线程,它像极了C语言的scanf(),一旦启动就会一直侦听下去,直到读取到内容才会执行下面的代码,这样的话,子线程就变成了死锁,无法继续往下执行。

好了,线程的实际应用就到这里,欢迎下方留言,指出不足,让我们携手共进!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值