温习了一下java线程状态方面的知识总结一

好长时间没有复习线程状态这块,读并发编程实战正好看着这块,顺便复习一下:

1.线程的五种状态:

2.线程五种状态的转换图:

  1.  wait()会立刻释放synchronized(obj)中的锁以便其它线程可以执行obj.notify 
  2. 但是notify() 不会立即释放synchronize(obj)中必须等nofity所在线程执行完 synchronize(obj)块中所有代码才能释放这把锁
  3. Thread.sleep(long millisecond) 来挂起线程,sleep 可以给优先级低的线程执行,但是它不会释放锁,就是说如果有synchronizde 代码块其他的线程仍然不能访问
  4. Thread.yield()可以给其他线程执行的机会。如果没有其他线程此方法没有任何作用,于sleep() 类似就是有synchronize则同步块其他线程仍然不能访问共享数据。
  5. 总之:参考: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;
	}

	@Override
	public 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 block
			e.printStackTrace();
		}
		// TODO Auto-generated method stub
		super.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;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		int 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 block
				e.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 block
				e.printStackTrace();
			}
		}
			
		seq=value;
		available=true;
		notify();
	}
	
	


}

执行结果:

猜你喜欢

转载自blog.csdn.net/JHON07/article/details/83474362