线程小总结

  • java线程的五大基本状态  
1,新建状态(new):当前对象创建后,即进入新建状态,如:Thread t = new Thread();
2,就绪状态(Runnable):当调用对象的start()方法后,线程就进入就绪状态,处于就绪状态的线程需要等待CPU调度执行,不是说执行了start()方法之后线程就会执行
3,运行状态(Running):当CPU开始调度处于就绪状态的线程时,此线程才开始执行,即进入运行状态,就绪状态是进入运行状态的唯一状态,也就是说,线程想要执行,就必须先处于就绪状态
4:阻塞状态(Blocked):线程由于某种原因,暂时放弃了对CPU的使用权停止执行,则线程进入了阻塞状态,阻塞状态又可以分为以下三种:
   1)等待阻塞: 运行状态中,线程执行wait(),
   2)同步阻塞:线程在获取synchronized同步锁失败
   3)其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5.死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

  •   java线程创建的三种基本形式  
 继承Thread类重写run()方法
public class BallThread  extends Thread{
	public void run() {
		System.out.println("线程正在执行");
	}
}
	public static void main(String[] args) {
		BallThread ball = new BallThread();
		ball.start();
	}
  • 实现接口Runnable,重写接口里的run()方法
    public class MyRunnable implements Runnable{
    	public void run() {
    		System.out.println("线程正在执行");
    	}

    public static void main(String[] args) {
    	     
    		MyRunnable  m = new MyRunnable();//创建接口对象
    		Thread th = new Thread(m); //将接口对象当作参数传到Thread类里面
    		th.start();
    		
    	}

  • 匿名线程
    	public static void main(String[] args) {
    	     new Thread(){
    	    	 public void run(){
    	    		 System.out.println("开启线程");
    	    	 }
    	     }.start();
    		
    	}
    使用线程注意:当所用类不需要继承其他类时,大多使用直接继承Thread,当线程需要继承其他类时,就以实现接口的方式,当线程逻辑较为简单时使用匿名线程的方式  

    • 线程的同步问题
    • 1.同步方法 
          即有synchronized关键字修饰的方法。 
          由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 
          内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
          代码如: 
          public synchronized void save(){}

    • 2.同步代码块 
          即有synchronized关键字修饰的语句块。 
          被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
      	public int getCash(int cash) {
      		synchronized (this) {  //注意这个锁里面的对象需要一致不然达不到锁的效果
      			if (cash > count) {
      				System.out.println("你的余额不足,请重新输入");
      				return -1;
      			}
      			try {
      				Thread.sleep(100);
      			} catch (InterruptedException e) {
      				// TODO 自动生成的 catch 块
      				e.printStackTrace();
      			}
      			count = count - cash;
      			System.out.println("取钱成功,取钱额度为:" + cash + "余额为:" + count);
      			return count;
      		}
      	}

    1. 1. wait()与notify()/notifyAll()
        调用sleep()和yield()的时候锁并没有被释放,而调用wait()将释放锁。这样另一个任务(线程)可以获得当前对象的锁,从而进入它的synchronized方法中。
        只能在同步控制方法或同步块中调用wait()、notify()和notifyAll()。如果在非同步的方法里调用这些方法,在运行时会抛出IllegalMonitorStateException异常。
         可以通过notify()/notifyAll(),或者时间到期,从wait()中恢复执行。

例如:
  synchronized(obj) {
  while(!condition) {
  obj.wait();
  }
  obj.doSomething();
  }
  当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。
  在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A :
  synchronized(obj) {
  condition = true;
  obj.notify();
  }
  需要注意的概念是:
  
  # 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj){...} 代码段内。

  # 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj){...} 代码段内唤醒A。

  # 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
  #如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
  #obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
  # 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行


一,线程池的基本要素线程池一般需要一个线程管理类: ThreadPoolManager,其作用有:

1)提供创建一定数量的线程的方法。主线程调用该方法,从而创建线程。创建的线程执行自己的例程,线程的例程阻塞在任务抓取上。

 2)提供对任务队列的操作的方法。主线程调用初始化任务队列的方法,然后在有任务的时候,调用提供的任务添加方法,将任务添入等待队列。当主线程调用任务的添加方法时,会触发等待的线程,从而使得阻塞的线程被唤醒,其抓取任务,并执行任务。线程池需要一个任务队列: List<Task>,其作用有:

  提供任务的增删方法。而且该任务队列需要进行排他处理,防止多个工作线程对该任务队列进行同时的抓取操作或者主线程的加入与工作线程的抓取的并发操作。

线程池需要一个类似信号量的通知机制:wait -notify:工作线程调用wait阻塞在任务抓取上。主线程添加任务后,调用notify触发阻塞的线程。

 线程池需要一个线程类:WorkThread,其作用有:

  提供线程的例程。创建线程WorkThread后,需要抓取任务,并执行任务。这是线程的例程。

线程池需要一个任务类:Task,其作用有:

  提供线程抓取并执行的任务目标。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值