在读Thinking in Java中并发的笔记(1)

  1. Wait()方法

    1.wait()有两种形式,第一种版本是接受毫秒数作为参数,含义与sleep()方法里参数的意思相同,都是指"在此期间暂停"。但是与sleep()不同的是,对于wait()而言
    1)在wait()期间锁是释放的
    2)可以通过notify()和notifyAll(),或者命令时间到期从wait()中恢复执行。
    第二种版本,wait()不接受任何参数。将无限等待下去,直到线程接收到notify()或者notifyAll()的消息。

    2.wait()、notify()、notifyAll()是基类Object的一部分,不是属于Thread的一部分。
    实际上,只能再同步方法里调用wait()、notify()、notifyAll()(因为不用操作锁,所以sleep()可以再非同步控制方法里调用。)。如果在同步方法里调用这些方法,程序能通过编译,但运行的时候,将得到IllegalMontorStateException异常,并伴随一些含糊的消息,比如"当前线程不是拥有者"。意思是调用wait()、notify()、notifyAll()的任务必须在调用这些方法前拥有对象的锁。

例:如果要向对象x发送notifyAll(),那么就必须在能够获取到x的锁的同步块中这么做:

synchronized(x){
		x.notifyAll();
	}
  1. interrupt() 中断,interrupted()检查中断
    常用用法:
try {
			while(!Thread.interrupted()){
				dosomething();
			} 
		}catch (InterruptedException e) {
			System.out.println("Butterer interupted");
			e.printStackTrace();
		}
  1. 生产者与消费者队列
    由于刚开始学java,所以手打这个比较重要的案例。希望可以从中学到一些优秀的编程习惯。之前的Sftp连接池有点菜 哈哈
/**
 *专有/保密源代码,未经许可禁止任何人通过任何* 渠道使用、修改源代码.
 * 日期 2019年4月23日 下午11:15:12
 */
package com.cgb.prodConsumer;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @project: Thread
 *
 * @version: V1.0
 *
 * @author: lz
 *
 * @date: 2019年4月23日 下午11:15:12	
 *
 * @class: com.cgb.prodConsumer.ToastMatc
 *
 * @description
 * <p>
 * 
 * </p>
 */

class Toast{
	//干的,吐奶油的,果酱
	public enum Status {DRY, BUTTERED, JAMMED}
	private Status status = Status.DRY;
	private final int id;
	public Toast(int idn){ id = idn;}
	public void butter(){
		status = Status.BUTTERED;
	}
	public void jam(){
		status = Status.JAMMED;
	}
	public Status getStatus(){
		return status;
	}
	public int getId(){
		return id;
	}
	public String toSting(){
		return "Toast"+id+":"+status;
	}
}
/**
 * 创建一个新的干吐司对象,并将该干吐司塞入干吐司队列,等待抹奶油方法处理
 * 
 * @date: 2019年4月24日 上午12:02:29	
 *
 * @class: com.cgb.prodConsumer.ToastQueue
 *
 */
class ToastQueue extends LinkedBlockingQueue<Toast>{}

class Toaster implements Runnable{
	private ToastQueue toastQueue;
	private int count = 0;
	private Random rand = new Random(47);
	public Toaster(ToastQueue tq) {
		toastQueue = tq;
	}
	@Override
	public void run() {
		try {
		while(!Thread.interrupted()){
			TimeUnit.MILLISECONDS.sleep(100+rand.nextInt(500));
			//生产一个吐司
			Toast t = new Toast(count++);
			System.out.println(t.toSting());
			//插入队列
			toastQueue.put(t);
		}
		} catch (InterruptedException e) {
			System.out.println("Toaster interrupted");
			e.printStackTrace();
		}
		System.out.println("Toaster off");
	}
	
}
/**
 * 抹奶油方法,从干吐司队列中取出吐司,将状态置为奶油状态后塞入奶油队列
 *
 * @author: lz
 *
 * @date: 2019年4月24日 上午12:01:09	
 *
 * @class: com.cgb.prodConsumer.Butterer
 *
 */
class Butterer implements Runnable{
	private ToastQueue dryQueue,butteredQueue;
	public Butterer(ToastQueue dry,ToastQueue buttered){
		dryQueue = dry;
		butteredQueue = buttered;
	}
	@Override
	public void run() {
		try {
			while(!Thread.interrupted()){
				//获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。
				Toast t = dryQueue.take();
				t.butter();
				System.out.println(t.toSting());
				butteredQueue.put(t);
			} 
		}catch (InterruptedException e) {
			System.out.println("Butterer interupted");
			e.printStackTrace();
		}
		System.out.println("Butterer off");
	}
}
/**
 * 
 * 抹果酱方法,从抹奶油队列取出抹了果酱以后塞入完成队列。供食用方法读取
 * 
 * @author: lz
 *
 * @date: 2019年4月24日 上午12:03:42	
 *
 * @class: com.cgb.prodConsumer.ToastMatc
 *
 */
class Jammer implements Runnable{
	private ToastQueue butteredQueue,finishedQueue;
	public Jammer(ToastQueue buttered ,ToastQueue finished) {
		butteredQueue = buttered;
		finishedQueue = finished;
	}
	@Override
	public void run() {
		try {
			while(!Thread.interrupted()){
				//获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。
				Toast t = butteredQueue.take();
				//置为抹果酱状态
				t.jam();
				System.out.println(t.toSting());
				finishedQueue.put(t);
			}
		} catch (InterruptedException e) {
			System.out.println("Jammer interrupted");
			e.printStackTrace();
		}
		System.out.println("Jammer off");
	}
}
/**
 * 食用方法
 * @author: lz
 *
 * @date: 2019年4月24日 上午12:13:47	
 *
 * @class: com.cgb.prodConsumer.Eater
 *
 */
class Eater implements Runnable{
	private ToastQueue finishedQueue;
	private int counter = 0;
	public Eater(ToastQueue finised){
		finishedQueue = finised;
	}

	@Override
	public void run() {
		try {
			while(!Thread.interrupted()){
				Toast t = finishedQueue.take();
				//如果不是按照顺序生成的或者生产的吐司没有抹果酱
				if(t.getId() != counter++ || 
					t.getStatus()!=Toast.Status.JAMMED ){
					System.out.println(">>>Error:"+t.toSting());
					System.exit(1);
				}else{
					System.out.println("Chomp!"+t.toSting());
				}
			} 
		}catch (InterruptedException e) {
			System.out.println("Eater interrupted");
			e.printStackTrace();
		}
		System.out.println("Eater off");
	}
}

//main方法
public class ToastMatic {
	public static void main(String[] args) throws Exception {
		ToastQueue dryQueue = new ToastQueue(),
				   butteredQueue = new ToastQueue(),
				   finishedQueue = new ToastQueue();
		
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(new Toaster(dryQueue));
		exec.execute(new Butterer(dryQueue, butteredQueue));
		exec.execute(new Jammer(butteredQueue, finishedQueue));
		exec.execute(new Eater(finishedQueue));
		TimeUnit.SECONDS.sleep(5);
		exec.shutdown();
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值