多线程备忘【JAVA】

 1、定义线程的方法:
  1.1 继承Thread类
  1.2 实现Runnable接口
 2、线程的生命周期
 New(新建):当一个线程对象被创建后,线程就处于新建状态。
             在新建状态中的线程对象从严格意义上看还只是一个普通的对象,它还不是一个独立的线程。
             处于新建状态中的线程被调用start方法后就会进入准备状态。
             从新建状态中只能进入准备状态,并且不能从其他状态进行新建状态。
             新建状态是线程生命周期的第一个状态。
 Runnable(准备):处于新建状态中的线程被调用start方法就会进入准备状态。
              处于准备状态下的线程随时都可能被系统选择进入运行状态,从而执行线程。
              可能同时有多个线程处于准备状态,对于哪一个线程将进入运行状态是不确定的。
              线程从新建状态进入到准备状态后是不可能再进入新建状态的。
              在等待/阻塞状态中的线程被解除等待和阻塞后将不直接进入运行状态,而是首先进入准备状态,让系统来选择哪一个线程进入运行状态。
 Running(运行):处于准备状态中的线程一旦被系统选中,使线程获取了CPU时间,就会进入运行状态。在运行状态中将执行线程类run方法中的程序语句。
                  线程进入运行状态后也不是一下执行结束的,线程在运行状态下随时都可能被调度程序调度回准备状态。
                  在运行状态下还可以让线程进入到等待/阻塞状态。
                  在通常的单核CPU中,在同一时刻只有一个线程处于运行状态的。在多核的CPU中,就可能两个线程或者更多的线程同时处于运行状态,这也是多核CPU运行速度快的原因
 Blocked(等待、阻塞):在Java中定义了许多线程调度的方法,包括睡眠、阻塞、挂起和等待,使用这些方法都会将处于运行状态的线程调度到等待/阻塞状态。
                       处于等待/阻塞状态的线程被解除后,不会立即回到运行状态,而是首先进入准备状态,等待系统的调度。
 Dead(死亡):当线程中的run方法执行结束后,或者程序发生异常终止运行后,线程会进入死亡状态。
              处于死亡状态的线程不能再使用start方法启动线程,但是这不代表处于死亡状态的线程不能再被使用,它也是可以再被使用的,只是将被作为普通的类来使用。
 
 3、线程的调度
 通过系统自动调度,线程的执行顺序是没有保障的。
 在Java中定义了一些线程调度的方法,使用这些方法在一定程序上对线程进行调度,使用这些方法只是给线程一个建议,具体是否能够成功,也是没有保障的。
 线程调度的方法有几个,包括睡眠方法、设置优先级、让步方法等
 3.1 睡眠方法
 当线程处于运行状态时,调用sleep睡眠方法将使线程从运行状态进入等待/阻塞状态,从而使程序停止运行。
 sleep睡眠方法是具有一个时间参数的,当经过这么长时间后,线程将进入准备状态,等待系统的调度。
 从而可以看出,当线程调用睡眠方法后,要想回到运行状态,需要的时间要比指定的睡眠时间长。
 sleep方法只是给线程一个调度的建议,是否调度成功是不能确定的
 sleep方法的基本语法:
 public static void sleep(long millis);(毫秒)
 public static void sleep(long millis,int nanos);(毫秒,纳秒)
 3.2设置优先级
 不同的线程可以具有不同的优先级,优先级高的线程就会占用更多的CPU资源和被执行概率。
 Java中的优先级是采用从1到10来表示的,数字越大表示优先级越高。如果没有为线程设置优先级,则线程的优先级为5,这也是线程的默认值。
 当需要对线程的优先级进行设置时,可以通过调用setPriority方法来设置。setPriority方法的语法:
 public final void setPriority(int i);(0<=i<=10或者Thread.MAX_PRIORITY,Thread.NORM_PRIORITY,Thread.MIN_PRIORITY)
 3.3让步方法
 3.3.1 yield让步方法
 yield让步方法是让线程让出当前CPU,而将CPU让给哪一个线程是不确定的,由系统来进行选择。使用yield让步方法的线程将从运行状态进入到准备状态。
 yield让步操作是可能不成功的。因为在线程中使用yield方法,使该线程进入准备状态。但是系统是有可能再次选择该线程,使该线程进入运行状态的。
 yield让步方法的基本语法:public static void yield(); 静态方法与对象无关。
 3.3.2 join让步方法
 使用join让步方法,可以将当前线程的CPU资源让步给指定的线程。
 join让步方法的语法格式:
 public final void join(); 指定的线程执行完成后再执行其他线程
 public final void join(long mills);在参数的时间内执行让步给的执行线程
 public final void join(long millis,int nanos);在参数的时间内执行让步给的执行线程
 与对象有关,所以可以让步给指定线程。
 4、加锁
 多个线程同时对同一对象的状态做操作时可能会出现相互倾轧现象,造成不准确,于是引入锁的概念,对代码块加锁后可以保证不受并发访问的困扰。
 4.1 ReentrantLock类加解锁
 ReentrantLock lock = new ReentrantLock();
 lock.lock();
 ......
 lock.unlock();
 4.2 Synchonzied关键字加锁
 在方法申明中添加Synchonzied关键字即可,例如:
 private synchonized void lock();
 4.3 读写锁
 ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
 Lock readLock = lock2.readLock();
 Lock writeLock = lock2.writeLock();
 加读锁(给访问者)
 readLock.lock();
 ......
 readLock.unlock();
 加写锁(给修改者)
 writeLock.lock();
 ......
 writeLock.unlock();

 

5、线程生命周期图示

 

线程生命周期图示

 

 

 

 

 

 

 

 

 

 

 

 

 

6、代码使用例子:

public class ThreadTest01 {
	
	/**
	 * 继承Thread类的方式来定义线程
	 * @author Denny
	 *
	 */
	 class Thread01 extends Thread{

		@Override
		public void run() {
			for(int i =0;i<10000000;i++){}
			ReentrantLock lock = new ReentrantLock();
			lock.lock();
			System.out.println("线程1运行中[继承Thread类]");
			lock.unlock();
		}
		 
	 }
	 /**
	  * 实现Runnable接口的方式定义线程
	  * @author Denny
	  *
	  */
	 class Thread02 implements Runnable{

		public void run() {
			for(int i = 0;i<10000000;i++){}
			System.out.println("线程2运行中[实现Runnable接口]");
		}
		 
	 }
	 /**
	  * 线程使用
	  * @param args
	 * @throws InterruptedException 
	  */
	 public static void main(String[] args) throws InterruptedException {
		//对象声明及调用[继承Thread类]
		Thread01 tr = new ThreadTest01().new Thread01();
		tr.start();
		System.out.println("线程开始等待");
		Thread.sleep(1000*2);
		System.out.println("线程结束等待");
		//对象声明及调用[实现Runnable接口]
		Thread02 temp = new ThreadTest01().new Thread02();
		Thread tr2 = new Thread(temp);
		tr2.start();
		System.out.println("线程开始让步");
		tr2.join(1000*2);
		System.out.println("线程结束让步");
 
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值