Java多线程基础知识整理二

   线程状态
   * 新生状态:用new关键字和thread类或其子类建立一个线程对象后,该线程对象就处于新生状态,处于新生状态的
 * 线程拥有自己的内存空间,通过调用start方法进入就绪状态
  *  就绪状态:处于就绪状态的线程已经具备了运行条件,但还没有分配到cpu,处于线程就绪队列,等待系统为其分配cpu,
 *  等待系统为其分配cpu,等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,他就会从等待执行状态
 *  执行状态,系统挑选的动作称之为cpu调度,一旦获得cpu,线程就进入运行状态并自动调用自己的run方法;
 *   运行状态: 在运行状态的线程执行自己run方法的代码,直到调用其他方法而终止,或等待某资源而阻塞或完成任务而死亡
 *   ,如果在给定的时间内没有执行结束,就会被系统给换下来回到等待执行状态;
 *   阻塞状态
 *   处于运行状态的线程在某些情况下,如执行了sleep睡眠方法,或等待I/O设备等资源,将让出cpu并暂时停止自己的运行
 *   进入阻塞状态,在阻塞状态的线程不能进入就绪队列,只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来
 *   ,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来的位置开始继续运行
 *   死亡状态:
 *    死亡状态时线程生命周期中的最后一个阶段,线程死亡的原因有两个,一个是正常运行的状态完成了它的全部工作
 *    另一个是线程被强制性的终止,如通过stop或destroy方法来终止一个线程(不推荐使用这两个方法,前者会产生异常,后者是强制终止
 *    ,不会释放锁)

停止线程:
 *  1.自然终止:线程体常执行完毕
 *   外部干涉:
 * 1.线程内中定义线程体中使用的标志;
 * 2.线程体使用该标志;
 * 3.提供对外的方法改变该标志

package Tread;

public class Thread06 {
	public static void main(String[] args) {
		Study s = new Study();
		new Thread(s).start();
		for (int i = 0; i < 1000; i++) {
			if (i == 50) {
				s.setFlag(false);
			}
			System.out.println("main" + "-----------" + i);
		}

	}
}

class Study implements Runnable {
	private boolean flag = true;

	@Override
	public void run() {
		while (flag) {
			System.out.println("Thread stop.....");
		}
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

}

 阻塞线程(一)

 1.join:合并线程,下图代码阻塞了main方法;

package Tread;

public class JoinDemo implements Runnable {
	public static void main(String[] args) throws InterruptedException {
		JoinDemo j = new JoinDemo();
		Thread t = new Thread(j);
		t.start();
		for (int i = 0; i < 1000; i++) {
			if (50 == i) {
				t.join();
			}
			System.out.println("main...." + i);
		}
	}

	@Override
	public void run() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("join...." + i);
		}
	}
}

  


 * 2.yield:暂停自己的线程,让出cpu的调度:静态方法,

package Tread;

public class YieldDemo implements Runnable {
	public static void main(String[] args) throws InterruptedException {
		YieldDemo j = new YieldDemo();
		Thread t = new Thread(j);
		t.start();
		for (int i = 0; i < 1000; i++) {
			if (i % 20 == 0) {
				Thread.yield();
			}
			System.out.println("main...." + i);
		}
	}

	@Override
	public void run() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("yiled" + "...." + i);
		}
	}
}

 , 3.sleep:线程休眠时不会释放锁 经常用于两种情况:与时间相关的:倒计时 模拟网络延时 

package Tread;

public class SleepDemo {
	public static void main(String[] args) throws InterruptedException {
		int num = 10;
		while (true) {
			Thread.sleep(1000);
			System.out.println(num--);
			if (num < 0) {
				break;
			}
		}
	}
}

 模拟倒计时

package Tread;

import java.text.SimpleDateFormat;
import java.util.Date;

public class SleepDemo01 {
	public static void main(String[] args) throws InterruptedException {
		Date endtime = new Date(System.currentTimeMillis() + 10 * 1000);
		long end = endtime.getTime();
		while (true) {
			Thread.sleep(1000);
			System.out.println(new SimpleDateFormat("mm:ss").format(endtime));
			endtime = new Date(endtime.getTime() - 1000);
			if (end - 10000 > endtime.getTime()) {
				break;
			}

		}
	}
}

模拟网络延时

public class Demo  {
	public static void main(String[] args) {
		Web12306 wb = new Web12306();
		Thread t1 = new Thread(wb, "黄牛");
		Thread t2 = new Thread(wb, "黄牛2");
		Thread t3 = new Thread(wb, "工程师");
		t1.start();
		t2.start();
		t3.start();
	}
}
class Web12306 implements Runnable {
	int num = 10;
	private boolean flag = true;

	@Override
	public void run() {
		while(true) {
			if (num <= 0) {
				break;
			}
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "抢到了" + num-- + "票");
		}
	}

  

原文地址:https://www.cnblogs.com/yjxs/p/9848344.html