进程和线程

进程和线程

进程

在计算机中,我们运行的每一个应用程序都可以看做一个进程,它是计算机中某个数据集合的一次运行活动。以单核cpu来讲,cpu在同一时间只能完成一个任务,也就是同一时间内只能执行一个进程。

线程

一个进程在运行过程中又包括很多个线程,这些线程共同完成一个任务(大概可以理解为把大问题化小逐个解决)。比如食堂卖饭(目的是卖完当天的库存),而食堂有很多个窗口麦不同的东西,但是他们访问的都是同样的库存(多个线程协同完成任务)。

线程的状态

一个线程的一生包括以下状态:
1.初始态:线程刚创建时的状态
2.就绪态:执行start()方法后线程进入就绪态
3.运行态:当cpu分配时间片给该线程时即进入运行台
4.阻塞态:当该线程的时间片结束时,线程会进入阻塞态,随后接触阻塞进入就绪态等待下一个时间片
5.销毁:线程执行完毕后销毁
在这里插入图片描述

线程的创建和启动

在java中,主要有以下几种创建线程的方式:
1.实现Runnable接口并实现其中的run方法
2.继承Thread类并重写其中的run方法
3.实现Callable接口
4.使用ExecutorService,Callable等相关接口
实际上这其中最常用的就是前两个Runnable和Thread,这里就只讲下这两种的用法(其实是我暂时只学到在这两种):

1.实现Runnable接口(实现run方法)
public class MyThread implements Runnable{

	private String name;
	
	public MyThread(String name) {
		this.name = name;
	}

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			System.out.println(name+":--->"+i);
		}
	}
	
	public static void main(String[] args) {
		
		MyThread mt1 = new MyThread("t1");
		MyThread mt2 = new MyThread("t2");
		
        //创建线程对象
		Thread t1 = new Thread(mt1);
		Thread t2 = new Thread(mt2);
		//线程启动
		t1.start();
		t2.start();
	}

}

2.继承Thread类(重写run方法)
public class MyThread2 extends Thread{

	
	public void run() {
		for (int i = 0; i < 20; i++) {
			System.out.println(this.getName()+"---->"+i); 
		}
	}
	
	public static void main(String[] args) {
		
		MyThread2 mt1 = new MyThread2();
		MyThread2 mt2 = new MyThread2();
		
		mt1.start();
		mt2.start();
		
	}
}

这两个本质上区别不大,反倒是用Runnable的时候启动线程时反而还要稍微麻烦一点点。但是Runnable的优势在于实现Runnable的同事还可以实现其他接口或者继承一个其他的类。

线程的终止

在线程执行过程中,我们往往需要在它达成特定条件后就将其终止,这就涉及到了以下两种方法:
1.标记中断法
2.异常中断法

标记中断法

其原理是声明一个标记变量(类型一般是整形或布尔型吧),在线程达到目的是将标记设置成可终止状态,然后用return终止进程:

public class ThreadEnd extends Thread{

	@Override
	public void run() {
		boolean isOver = false;
		int i = 0;
		while(!isOver){
			System.out.println(this.getName()+"-->"+i);
			i++;
			if(i >= 50000){
				isOver = true;
				return;
			}
		}
		System.out.println("确定结束了么?这是线程内部的输出!");
	}
	
	public static void main(String[] args) {
		
		ThreadEnd te = new ThreadEnd();
		te.start();
		
	}
}
异常中断法

这种方法就像名字一样,在满足条件后抛出异常终止进程

public class ThreadEnd2 extends Thread{

	@Override
	public void run() {
		try {
			for (int i = 0; i < 1000000; i++) {
				System.out.println(this.getName()+"-->"+i);
				if(this.isInterrupted()){
					throw new InterruptedException("当前线程被中断!!!");
				}
			}
		} catch (InterruptedException e) {
			System.out.println("线程终止");
			e.printStackTrace();
		}
	} 
	
	public static void main(String[] args) throws InterruptedException {
		ThreadEnd2 te2 = new ThreadEnd2();
		te2.start();
		
		Thread.sleep(2000);
		//中断线程
		te2.interrupt();
	}
	
}

另外Thread中的stop()方法也可以终止进程,但是这种方法因为不安全已经淘汰了,不建议使用。

守护线程

守护线程就是为其他线程提供服务的线程,也可用于监视某一线程的进度之类的,而且主进程结束时守护进程也会随之结束。

public class BackService extends Thread{
	@Override
	public void run() {
		int i = 1;
		while(true){
			try {
				System.out.println("后台线程(守护线程)正在执行:"+i);
				i++;
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

主线程:

public class ThreadDeamon extends Thread{
	
	@Override
	public void run() {
         //创建线程对象
		BackService bs = new BackService();
		//设置当前线程为守护线程
		bs.setDaemon(true);
		bs.start();
		try {
			for (int i = 0; i < 1000; i++) {
				sleep(2);
				System.out.println("执行线程---->"+i);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		new ThreadDeamon().start();
	}

}

多线程编程

在实际应用中,通常会遇到两个或多个线程要对同一条数据进行修改,例如银行取钱,两个地方用同一账号取钱,账号上只有10000而两个进程并发都要取10000,如果不做处理的话两边都会取到10000,而银行反亏10000,这极不合理。因此在遇到这一类问题时,通常通过synchronized给两个线程共享的缓冲区上锁,这样在一个线程占用资源时另一个线程会进入等待状态,等到前一个线程释放资源时再调用资源,这样就能解决多线程并发问题。

private Object obj;
	private String name;
	public WaitThread(Object obj, String name) {
		super();
		this.obj = obj;
		this.name = name;
	}
	
	@Override
	public void run() {
		System.out.println(name+"进入run...");
		
		//CAS锁(乐观锁)
		//悲观锁
		synchronized(obj){
			
			try {
				System.out.println(name + "等待...");
				//只有当前线程拥有指定对象的锁(对象监视器)才能调用wait方法,并且wait一旦执行
				//该对象的锁就会被释放
				obj.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		System.out.println(name+"执行结束...");
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值