好长时间没有复习线程状态这块,读并发编程实战正好看着这块,顺便复习一下:
1.线程的五种状态:
2.线程五种状态的转换图:
- wait()会立刻释放synchronized(obj)中的锁以便其它线程可以执行obj.notify
- 但是notify() 不会立即释放synchronize(obj)中必须等nofity所在线程执行完 synchronize(obj)块中所有代码才能释放这把锁
- Thread.sleep(long millisecond) 来挂起线程,sleep 可以给优先级低的线程执行,但是它不会释放锁,就是说如果有synchronizde 代码块其他的线程仍然不能访问
- Thread.yield()可以给其他线程执行的机会。如果没有其他线程此方法没有任何作用,于sleep() 类似就是有synchronize则同步块其他线程仍然不能访问共享数据。
- 总之:参考:https://blog.csdn.net/wangpei555/article/details/61414447
- 调用join方法后,线程阻塞,线程失去对该对象锁的持有,失去cpu.
- sleep方法执行后,处于阻塞状态,线程会交出cpu,对该对象的锁没有交出,其他线程也无法访问该对象。
- 调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁。
3.看一个简单的生产者和消费者的列子
生产者的列子:
package com.asiainfo.producer;public class Producer extends Thread {private CubbyHole cubbyhole;private int num;Producer(CubbyHole cubbyhole, int num) {this.cubbyhole = cubbyhole;this.num = num;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {cubbyhole.put(i);System.out.println("Producer#" + this.num + "put:" + i);}try {sleep((int) Math.random() * 100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}// TODO Auto-generated method stubsuper.run();}
}
消费者:
package com.asiainfo.producer;public class Consumer extends Thread {private CubbyHole cubbyhole;private int num;Consumer(CubbyHole cubbyhole,int num){this.cubbyhole=cubbyhole;this.num=num;}@Overridepublic void run() {// TODO Auto-generated method stubint value=0;for(int i=0;i<10;i++){value=cubbyhole.get();System.out.println("Cusumber#"+this.num+"got"+value);}super.run();}}
共享的对象:
像CubbyHole 这样被多个线程同步线程共享的对象称为条件遍历;这里的条件变量就相当于一个监视器,java语言就是通过监视器来实现同步的。一个monitor 就相当于一个只能容纳一个线程的小盒子,在一点特定的时间里只能容纳一个线程进入monitor,而其他线程将被暂停知道当前线程离开这个盒子。
package com.asiainfo.producer;public class CubbyHole {private int seq;public synchronized int get() {return seq;}public synchronized void put(int seq) {this.seq = seq;}}
测试类:
package com.asiainfo.producer;public class Person {public static void main(String[] args) {CubbyHole cubbyHole = new CubbyHole();Consumer consumer = new Consumer(cubbyHole,1);Producer producer = new Producer(cubbyHole,2);producer.start();consumer.start();}}
产生的结果:
由于线程中不能保证,当producer 生产一个数据,就会被consumer 消费,有可能存在,竞争锁过程中,消费者,快于生产者,或者是生产者 快于消费者的状态,但是这两种状况都不是我们想要的;
改进后的CUbberHole 类;
package com.asiainfo.producer;public class CubbyHole {private int seq;//改进private boolean available =false;public synchronized int get() {while(available==false){try {/*** wait()会立刻释放synchronized(obj)中的锁以便其它线程可以执行obj.notify*/wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}available=false;/*** 但是notify() 不会立即释放synchronize(obj)中必须等nofity所在线程执行完 * synchronize(obj)块中所有代码才能释放这把锁*/notify();return seq;}public synchronized void put(int value) {while(available==true){try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}seq=value;available=true;notify();}}
执行结果: