Java学习笔记14 进程、线程

目录

一、基本概念

1.1 程序

1.2 进程(Process)

1.3 线程

1.4 多线程

1.5 进程与线程的区别

1.6 线程的生命周期

1.7 线程的状态

二、Java中线程的使用

2.1  自定义线程的两种方式

2.2 启动线程

2.3 实例


一、基本概念

1.1 程序

静态的。

是对数据描述和操作代码的集合,是应用程序执行的脚本。

 

1.2 进程(Process)

动态的。

是程序的一次执行过程,是系统运行程序的基本单位。

一个进程包括操作系统分配的内存空间、包含一个或多个线程。

 

1.3 线程

动态的。

是程序中相对独立的代码段,比进程更小的运行单位,多个线程构成一个进程。

 

1.4 多线程

在Java中,一个应用程序可以包含多个线程。每个线程执行特定的任务,并可以与其他线程并发执行。

多线程使系统的空转时间最少,提高CPU的利用率。

多线程编程环境用方便的模型隐藏CPU在任务间切换的事实。

多线程能够满足程序员编写高效率的程序来达到充分利用CPU的目的。

 

1.5 进程与线程的区别

进程有独立的内存和CPU。线程需要依附于进程。进程大,线程小。

进程之间的切换消耗资源多,效率低。

线程之间的切换消耗资源少,效率高。

进程:

进程由操作系统管理,系统可以为一个程序创建多个进程。

进程有自己的内存空间和CPU空间。

进程基于的多任务程序独立开发、独立运行,但切换通信成本大,占用资源多。

线程:

线程是由进程调度管理的,多个线程构成一个进程。

线程没有自己独立的内存空间和CPU时间,只能依附于进程。

基于线程的多任务程序通信成本低,调用资源少,但不能独立开发运行。

 

1.6 线程的生命周期

新建 new线程实例

就绪 调用start()方法

运行 线程抢到CPU,开始运行run()方法中的代码

      可能存在--阻塞field()、挂起suspend()、睡眠sleep()、等待wait()

死亡 run()方法中的代码执行完毕,或用stop(),destroy()函数强制终止

 

1.7 线程的状态

 

二、Java中线程的使用

 java.lang.Thread类-----------java线程类

线程类简单使用:

	public static void main(String[] args) {
		//java程序运行时,至少有两条线程:main线程、system.gc(垃圾回收)线程[守护线程]
		//得到当前的线程--main方法的线程
		Thread thread = Thread.currentThread();
		System.out.println("线程名称="+thread.getName()); //线程名称=main
		System.out.println("线程ID="+thread.getId()); //线程ID=1
		
		//线程的优先级1-10,默认为5,最高为10,最低为1
		System.out.println("线程优先级="+thread.getPriority()); //线程优先级=5
		System.out.println("线程最高优先级="+Thread.MAX_PRIORITY); //线程最高优先级=10
	}

2.1  自定义线程的两种方式

1)extends Thread ,重写run()

2)implements Runnable ,重写run() --推荐方法,单继承多实现

 

2.2 启动线程

通过线程的实例调用start()方法,让线程进入 "就绪" 状态

进入就绪状态的线程,具备使用CPU的能力

如果就绪状态的线程获得CPU的使用权,则开始运行

如果就绪状态的线程没有获得CPU的使用权,则排队等待

 

2.3 实例

线程的两种定义方式即启动使用。

package com.company.mythread;
//自定义线程 继承java.lang.Thread类
public class MyThread1 extends Thread{
	public void run() {
		// 模拟长动作
		for (int i = 0; i < 100; i++) 
			if(i%2==0){
				System.out.println(i+"是偶数"); //线程1 输出0-100的偶数
				//通过代码的方式交出CPU
				try { Thread.sleep(1);} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
	}
}
package com.company.mythread;
// 自定义线程实现Runnable接口  implements Runnable
public class MyThread2 implements Runnable {
	//必须实现接口的run()方法	
	public void run() {
		for (int i = 0; i < 100; i++) {
			if(i%2==1) {
				System.out.println(i+"是奇数"); //线程2 输出0-100的奇数
				//通过代码的方式交出CPU
				try { Thread.sleep(1); } catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
public class TestThread {
	public static void main(String args[]) {
		//启动自定义的线程
		MyThread1 myThread1 = new MyThread1();
		myThread1.start();
		//调用start()方法启动线程,线程进入就绪状态
		//就绪的线程则具备的排队使用CPU的能力
		//当线程获得CPU时,就会运行
		//如果没有获得CPU,继续排队等待
		
		new Thread(new MyThread2()).start();
		// MyThread2()--使用实现接口的方法创建
		// 建议使用--单继承多实现
	}
}

输出结果:(不唯一)

 

7. 线程同步

线程同步--加锁,数据安全,效率低。

线程不同步--无锁,数据不安全,效率高。

在Java中获得线程同步:synchronized

1)同步方法 <访问修饰符> synchronized <返回值类型> methodA(){  //需要同步的代码  }

2)同步块 synchronized (object){  //需要同步的代码,object一般使用this,传入当前对象即可    }

同步实例:四个人抢购100张票。

// Tickets类

public class Tickets {
	private int count;
	public void saler() {
		System.out.println("票号"+count);
		count++;
	}
}

// 买票系统--同步方法

public class SalerTicket implements Runnable{
	private int count; //票数
	public SalerTicket(int count) {
		this.count = count;
	}
	public void run() {
		String name = Thread.currentThread().getName();
		while(count<=100) {
			methodA(name); //调用同步方法
			Thread.yield(); //购买一次票后阻塞该线程
		}
	}
	public synchronized void methodA(String name) {  //同步方法
		System.out.println(name+"买了票"+count);
		count++; //票自增1
	}	
}

//买票系统--同步块实现

public class SalerTicket implements Runnable{
	private int count; //票数
	public SalerTicket(int count) {
		this.count = count;
	}
	public void run() {
		String name = Thread.currentThread().getName();
		while(count<=100) {
			synchronized (this) { //同步块,传入object--this
				System.out.println(name+"买了票"+count);
				count++;
			}
			Thread.yield();
		}
	}
}

// 主函数--购票

public class SalerTest {
	public static void main(String[] args) {
		int count=1; //起始票号
		SalerTicket salerTicket = new SalerTicket(count);
		// 使用四个线程抢票
		new Thread(salerTicket,"人员1").start(); 
		new Thread(salerTicket,"人员2").start();
		new Thread(salerTicket,"人员3").start();
		new Thread(salerTicket,"人员4").start();
	}
}

// 运行购票

 

8.线程间的通信

8.1 wait-notify机制

为了避免轮流检测,Java提供了线程间通信机制--wait-notify机制,使用wait(),notify()和notifyAll()方法。

这些方法为Object类的final方法,只能在synchronized方法或synchronized块中使用。

wait()--告知被调用的线程退出监视器并进入等待状态,直到其他相同线程进入相同的监视器并调用notify()方法。

notify()--通知同一对象上第一个调用wait()的线程。

notifyAll()--通知调用wait()的所有线程,具有最高优先级的线程将先运行。

 

8.2练习 仓库货物存取问题

货物存取:高于20个,取货;低于5个进货

// 货物仓库类

public class Store {
	private int count = 0; //初始货物数量
	//放货物
	public void put() {
		synchronized (this) {
			if(count < 20) {//货物数量小于20,放货物
				count++;
				System.out.println("进货,存货:"+count);
			}else {// 货物充足,调用wait()
				try {  wait(); } catch (InterruptedException e) { 
					e.printStackTrace();
				}
			}
			notify();//唤醒其他线程工作
		}
	}
	//取货物
	public  void get() {
		synchronized(this) {
			if(count > 5) { //货物充足
				System.out.println("取货:"+count);
				count--;
			}else { //货物不够
				try { wait(); } catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			notify();//唤醒其他线程工作
		}
	}
}

//存放货物类

public class StorePutter implements Runnable{
	private Store store;
	public StorePutter(Store store) { //构造函数
		this.store = store;
	}
	public void run() { //重写run()方法
		while(true) {
			store.put(); //不停放货
		}
	}
}

//取出货物类

public class StoreGetter implements Runnable{
	private Store store;
	public StoreGetter(Store store) { //构造函数
		this.store = store;
	}
	public void run() { //重写run()方法
		while(true) {
			store.get(); //不停取货
		}	
	}
}

//测试主函数

public class StoreTestMain {
	public static void main(String[] args) {
		Store store = new Store(); //Store实例
		new Thread(new StorePutter(store)).start(); //放货线程
		new Thread(new StoreGetter(store)).start(); //取货线程
	}
}

运行:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值