-
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();
}
- interrupt() 中断,interrupted()检查中断
常用用法:
try {
while(!Thread.interrupted()){
dosomething();
}
}catch (InterruptedException e) {
System.out.println("Butterer interupted");
e.printStackTrace();
}
- 生产者与消费者队列
由于刚开始学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();
}
}