本人所有文章,只属学习整理及个人理解!有误还望谅解并指出,谢谢!持续更新中…
线程状态图
线程状态说明:
- 1、NEW: 线程对象已经创建,但是尚未启动的线程。
- 2、RUBBABLE: 正在 Java 虚拟机中执行的线程处于该状态。
- 3、BLOCKED:受阻塞并等待某个监视器锁的线程处于该状态。
- 4、WAITING:无限期地等待另一个线程来执行某个特定操作的线程处于该状态。
- 5、TIMED_WAITING:等待另一个线程来执行,取决于指定等待时间的操作的线程处于该状态。
- 6、TERMINATED:已经退出的线程处于该状态;
阻塞状态:具有cpu的执行资格,等待cpu空闲时执行
休眠状态:放弃cpu的执行资格,cpu空间,也不执行
消息队列的案例
- 图像化逻辑分析:
- 生产者代码如下:
public class Producer implements Runnable {
private final Queue<String> queue;
// private
public Producer(final Queue<String> queue){
this.queue = queue;
}
@Override
public void run() {
int i = 0;
while(true){
try {
Thread.sleep(1000); // 1 秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
this.queue.add("第"+(++i)+"个消息!");
System.out.println("生产者,生成了第"+i+"个消息");
}
}
}
- 消费者代码如下:
public class Customer implements Runnable {
private final Queue<String> queue;
// private
public Customer(final Queue<String> queue){
this.queue = queue;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000); // 1 秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费者,消费了"+this.queue.get());;
}
}
}
- 消息队列代码如下:
public class Queue<T> {
private LinkedList<T> queue = new LinkedList<T>();
private int min;
private int max;
private final static int QUEUE_SIZE_DEFAULT_MAX = 10;
public Queue(){
this(QUEUE_SIZE_DEFAULT_MAX);
}
public Queue(int maxSize){
this.max = maxSize;
}
// put linkedlist data
public synchronized void add(T t){
// this.queue.add(t);
// 当消息满的时候,进入等待
while (this.queue.size()== this.max){
// if (this.queue.size()== this.max){
try {
System.out.println("消息已满,开始等待");
this.wait();//等待是释放锁的
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// this.queue.addLast(t);
this.queue.addFirst(t);
this.notifyAll();// 队列不再空的时候,唤醒所有线程。唤醒所有线程
}
//get data for linkedlist
public synchronized T get(){
// 当消息为空的时候,进入等待
while (this.queue.size() == 0){
// if (this.queue.size() == 0){
//队列为空,进入等待
try {
System.out.println("消息为空,开始等待");
this.wait(); // if()在这里等待的那个线程,被唤醒后,重新持锁,会从该处继续执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//这便需要考虑,你设计的是队列,还是栈
// this.queue.getFirst();
T t = this.queue.getLast();
// 取用过的消息,不应该还在队列当中
this.queue.removeLast();
this.notifyAll();//队列不再满的时候,唤醒所有线程
return t;
}
}
- 具体测试代码如下:
public class MultithreadTest {
public static void main(String[] args) {
Queue<String> q = new Queue<String>();
Thread c1 = new Thread(new Producer(q));//生产者
c1.start();
Thread p1 = new Thread(new Customer(q));// 消费者
p1.start();
}
}
- 请看最后的运行结果:
生产者,生成了第1个消息
消费者,消费了第1个消息!
生产者,生成了第2个消息
消费者,消费了第2个消息!
生产者,生成了第3个消息
消费者,消费了第3个消息!
生产者,生成了第4个消息
消费者,消费了第4个消息!
生产者,生成了第5个消息
消费者,消费了第5个消息!
生产者,生成了第6个消息
消费者,消费了第6个消息!
生产者,生成了第7个消息
消费者,消费了第7个消息!
生产者,生成了第8个消息
消费者,消费了第8个消息!
上图属于个人理解所画,只求印象深刻。