对线程的认知

本文详细介绍了Java中的线程概念,包括线程的基本定义、多线程的优点、线程同步的重要性及其模型,并深入探讨了线程的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    一、线程的基本定义

         众所周知,线程是Java语言的一个重要知识点,我们要了解线程首先就要了解线程的基本定义。线程顾名思义就是进程中的单一执行流,进程用于自己的独立空间,而线程只能共享进程的空间,一个进程可以包含多个线程。

二、多线程的优点以及线程同步的概念

        前面我们已经了解了线程的基本定义,那么我们现在就来探讨一下线程有哪些优点以及线程同步到底有什么作用。

(1)多线程的优点:

    1.多线程可以同步并发的执行多个任务,当程序某个功能部分在等待某些资源时,此时又不愿意因为等待而造成程序暂停,那么就可以创建另外的线程进行其他工作。

    2.多线程可以最大限度的降低CPU的闲置时间,从而提高CPU的利用效率。

    下面我们就举个例子说明一下:读书和听音乐,如果我们先读书在听音乐或者先听音乐再读书,那么这样我们的效率就会大打折扣。如果我们现在换成一边听音乐一边读书,那么效率就会提高很多,线程也是同样的道理。

  (2)线程同步:

       要了解线程同步,我们可以通过了解线程同步的两个基本模型来了解线程同步的作用,即“监视线程”通讯模型以及“生产/消费者”模型。

1.“监视线程”通讯模型:即同时多个独立线程在运行,运行状态有第三方监控线程全程监控,这种就叫做“监视线程”通讯模型。下面我们通过银行取钱系统了解一下,在这个系统中我们有两个线程即ATM机与窗口取钱,他们的时间以及操作的对象即账户都相同。

主函数

package 线程;

public class test {
   public static void main(String[] args) {
	     Account acount=new Account(1000);
	     Consumer con1=new Consumer(acount, "ATM", 700);
	     Consumer con2=new Consumer(acount, "银行窗口", 700);
	     con1.start();
	     con2.start();
}
}
账户取款:注意在这里面我用到了一个synchronized 关键字,它的作用是锁定当前对象及方法

<pre name="code" class="java">package 线程;
/**
 *账户取款
 * @author Administrator
 *
 */
public class Account {
     //额度属性
	 private int count;
	 
	 public  Account(int count){
		 this.count=count;
	 }
	public int getmoney(int cash){
		synchronized (this) {
			if(count<cash){
				return -1;
			}
	        else{
	        	try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	        	count=count-cash;
	    	    return count;
			}
		}
		
		}
	}



取款的线程

package 线程;
/**
 * 取款的线程
 * @author Administrator
 *
 */
public class Consumer extends Thread{
       private Account acount;
       private String  way;
       private int cash;
       public Consumer(Account acount,String  way,int cash){
    	   this.acount=acount;
    	   this.way=way;
    	   this.cash=cash;
       }
	public void run(){
    	  int count=acount.getmoney(cash);
    	  if(count==-1){
    		  System.out.println("此次在"+way+"上操作失败,账户余额为"+count);
    	  }
    	  else{
    		  System.out.println("此次在"+way+"上操作成功,账户余额为"+count);
    	  }
       }
       
}
最后的运行结果就是:此次在银行窗口上操作失败,账户余额为-1
                                   此次在ATM上操作成功,账户余额为300

如果上面没有用到关键字synchronized 那么结果就会完全不同:

                                   此次在ATM上操作成功,账户余额为-400
                                   此次在银行窗口上操作成功,账户余额为300

很显然这是不行的,所以要达到我们预期的要求我们就必须要使用关键字synchronized

而且synchronized的位置要正确,千万不能放在if语句之后,不然就没有效果。

2.“生产/消费者”模型:在这里会用到方法wait()和notify(),他们的作用分别是等待和通知。

生产者

package 消费者;

import java.util.ArrayList;

public class Producter extends Thread{
	private ArrayList<Bnanel> arry;
	 private int n=1;
	public Producter(ArrayList<Bnanel> arry){
		this.arry=arry;
	}
    public void run(){
    	
    		while(true){
    		synchronized (arry) {
    			if(arry.size()>0){
        			try {
    					arry.wait();
    				} catch (InterruptedException e1) {
    					// TODO Auto-generated catch block
    					e1.printStackTrace();
    				}
                		
                	}
        		Bnanel bl=new Bnanel("香蕉的序号:"+n);
        		System.out.println("生产出香蕉型号为:"+bl.name);
        		n++;
        		arry.notify();
            	
            		try {
        				Thread.sleep(1000);
        			} catch (InterruptedException e) {
        				// TODO Auto-generated catch block
        				e.printStackTrace();
        			}
            	}
			}
    		
		}
    	
    }
消费者

<pre name="code" class="java">package 消费者;

import java.util.ArrayList;

public class Consumer extends Thread{
	private ArrayList<Bnanel> arry;
	public Consumer( ArrayList<Bnanel> arry){
		this.arry=arry;
	}
	   public void run(){
			while(true){
				synchronized (arry) {
	if(arry.size()==0){
		try {
		  arry.wait();
		} catch (InterruptedException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
		}
					    		 
	 }
		 Bnanel bl=arry.remove(0);
	  System.out.println("取出商品,商品的型号:"+bl.name);
		arry.notify();
						 
		try {
		Thread.sleep(1000);
		} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
					}
					      
				}
			}
          
	   }
}
    	 



产品

package 消费者;

public class Bnanel {
       public String name;
       public Bnanel(String name){
    	   this.name=name;
       }
}
主函数

package 消费者;

import java.util.ArrayList;

public class text {
       public static void main(String[] args) {
		ArrayList<Bnanel> arry=new ArrayList<Bnanel>();
		Producter pd=new Producter(arry);
		Consumer cm=new Consumer(arry);
		pd.start();
		cm.start();
		
	}
}
最后的运行结果为:

生产出香蕉型号为:香蕉的序号:1
生产出香蕉型号为:香蕉的序号:2
生产出香蕉型号为:香蕉的序号:3
生产出香蕉型号为:香蕉的序号:4
生产出香蕉型号为:香蕉的序号:5
。。。。。。
三、线程的生命周期

 线程的生命周期主要分为五个主要的部分,即新建、就绪、阻塞、运行、死亡。新建就是线程建立一个实例对象;就绪就是线程已经启动但等待CPU调用;阻塞就是由于主观或客观的原因,线程停止运行;运行就是线程获得CPU资源并且正在执行任务即run方法;死亡就是当线程执行完毕或由于其他原因不能运行就叫作线程的死亡。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值