进程及线程的常用方法

进程及线程的常用方法

一、进程

进程是系统进行资源分配和调用的独立单元,每一个进程都有它的独立内存空间和系统资源。

二、单进程操作系统和多进程操作系统的区别

1.单进程操作系统:dos(一瞬间只能执行一个任务)

2.多进程单用户操作系统:Windows(一瞬间只能执行多个任务)

3.多进程多用户操作系统:Linux(一瞬间只能执行多个任务)

三、现在的多核CPU是否可以让系统在同一个时刻可以执行多个任务吗?

理论上是可以的

四、线程

1.线程的介绍

1.线程是进程里面的一条执行路径,每个线程同享进程里面的内存空间和系统资源

2.一个进程 可以有 多个线程:各个线程都有不同的分工

2.线程和进程的关系

1.进程 与 进程之间的关系:进程之间的内存空间和系统资源是独立的

2.同一个进程里的多条线程 :线程之间的内存空间和系统资源是共享的

进程中:可以有一条或一条以上的线程

进程里只有一条线程的情况下,这条线程就叫做主线程

进程里有多条线程的情况下,主线程只有一条线程

注意:线程是在进程里的,他们是包含关系

五、我们应用的软件有哪些是多线程的应用

微信、QQ、支付宝、淘宝等等都是

六、Java中编写多线程

1.创建线程的方式 – 线程类

1.创建线程类:

1.创建类 – MyThread

2.继承Thread

3.重写run方法

2.启动线程:

1.创建线程类的对象:MyThread t = new MyThread();

2.启动线程:t.start();

public class Test01 {

	public static void main(String[] args) {
		
		//创建子线程
		MyThread t = new MyThread();
		
		//启动线程
		t.start();
	}
}
public class MyThread  extends Thread{

	//线程对象抢到CPU资源后才调用的方法
	//run方法的作用:该线程的功能都是编写在run方法中
	@Override
	public void run() {
		System.out.println("调用MyThread中的run()");
	}
}

2.创建线程的方式 – 任务类

1.创建任务类:

1.创建Task类

2.实现Runnable接口

3.重写run方法

2.启动线程:

1.创建线程对象:Thread t = new Thread(new Task());

2.启动线程:t.start();

public class Test01 {

	public static void main(String[] args) {
		
		//创建子线程(并将任务对象交给线程)
		Thread t = new Thread(new Task());
		
		//启动线程
		t.start();
	}
}
//任务类
public class Task implements Runnable {

	//线程对象抢到CPU资源后调用的方法
	//run方法的作用:该线程的功能都是编写在run方法中
	@Override
	public void run() {
		System.out.println("调用Task类中的run()");

	}

}

七、感受多线程之间争抢资源的场景

需求:编写一个多线程的应用程序,主线程打印1-100之间的数字,子线程打印200-300之间的数字,观察其输出的结果,体会多线程互相争抢资源的场景

public class Test01 {

	public static void main(String[] args) {
		
		MyThread t = new MyThread();
		t.start();//启动线程 -- 启动后,主线程抢到资源后代码就会向下执行
		
		for (int i = 1; i <= 100; i++) {
			System.out.println("主线程:" + i);
		}
	}
}
public class MyThread  extends Thread{

	@Override
	public void run() {
	for (int i = 200; i <=300; i++) {
		System.out.println("子线程:" + i);
		}
	}
}

八、线程的优先级别

需求:在主线程中创3个子线程,并且设置不同优先级,观察其优先级对线程执行结果的”影响”。

public class Test01 {

	public static void main(String[] args) {
		
		A a = new A();
		B b = new B();
		C c = new C();
		
		//设置优先级别
		a.setPriority(Thread.MAX_PRIORITY);//10
		b.setPriority(Thread.NORM_PRIORITY);//5
		c.setPriority(Thread.MIN_PRIORITY);//1
		
		a.start();
		b.start();
		c.start();
	}
}
public class A extends Thread{

	@Override
	public void run() {
	for (int i = 1; i <= 500; i++) {
		System.out.println("A:" + i);
	 }
	}
}
public class B extends Thread{

	@Override
	public void run() {
		for (int i = 1; i <= 500; i++) {
			System.out.println("B:" + i);
		}
	}
}

public class C extends Thread {

	@Override
	public void run() {
		for (int i = 1; i <= 500; i++) {
			System.out.println("C:" + i);
		}
	}
}


九、线程的命名

1.方案一

public class Test01 {

	public static void main(String[] args) {
		
		MyThread a = new MyThread("A");
		MyThread b = new MyThread("B");
		MyThread c = new MyThread("C");
		
		//设置优先级别
		a.setPriority(Thread.MAX_PRIORITY);//10
		b.setPriority(Thread.NORM_PRIORITY);//5
		c.setPriority(Thread.MIN_PRIORITY);//1
		
		a.start();
		b.start();
		c.start();
	}
}

public class MyThread extends Thread{

	private String threadName;

	public MyThread(String threadName) {
		this.threadName = threadName;
	}
	
	@Override
	public void run() {
		for (int i = 1; i <= 500; i++) {
			System.out.println(threadName + ":" + i);
		}
	}	
}

2.方案二

public class Test01 {

	public static void main(String[] args) {
		
		MyThread a = new MyThread("A");
		MyThread b = new MyThread("B");
		MyThread c = new MyThread("C");
		
		//设置优先级别
		a.setPriority(Thread.MAX_PRIORITY);//10
		b.setPriority(Thread.NORM_PRIORITY);//5
		c.setPriority(Thread.MIN_PRIORITY);//1
		
		a.start();
		b.start();
		c.start();
	}
}

public class MyThread extends Thread {

	public MyThread(String name){
		super(name);
	}
	
	@Override
	public void run() {
		// 获取当前线程的对象
		Thread thread = Thread.currentThread();
		
		for (int i = 1; i <=500; i++) {
			System.out.println(thread.getName() + ":" + i);
		}
	}
}

十、线程休眠

1.Thread.sleep(1000); – Thread类的静态方法

2.该方法写在哪个线程中,哪个线程就休眠(进入到阻塞状态)

需求:编写一个抽取学员回答问题的程序,要求倒数三秒后输出被抽中的学员姓名

import java.util.Random;

public class Test01 {

	public static void main(String[] args) throws InterruptedException{
		
		String[] names = {"孙权","周瑜","大乔","小乔","诸葛瑾"};
		
		Random ran = new Random();
		int index = ran.nextInt(names.length);
		
		for (int i = 3; i > 0; i--) {
			System.out.println(i);
			
			Thread.sleep(1000);
		  }
		
		System.out.println(names[index]);
	}
}

十一、线程的礼让

需求:创建两个线程A,B,分别各打印1-100的数字,其中B一个线程,每打印一次,就礼让一次,观察实验结果

public class Test01 {

	public static void main(String[] args) {
		
		A a = new A();
		B b = new B();
		
		a.start();
		b.start();
	}
}

public class A extends Thread{

	@Override
	public void run() {
		for (int i = 1; i <= 100 ; i++) {
			System.out.println("A:" + i);
	   }
	}	
}

public class B extends Thread {

	@Override
	public void run() {
		for (int i = 1; i <= 100 ; i++) {
			System.out.println("B:" + i);
			
			//礼让:让当前线程退出CPU资源,马上又进入到抢资源的状态
			Thread.yield();
		}
	}
}

十二、线程的合并

需求:主线程和子线程各打印200次,从1开始每次增加1,当主线程打印到10之后,

让子线程先打印完再打印主线程

public class Test01 {

	public static void main(String[] args) throws InterruptedException{
		
		MyThread t = new MyThread();
		t.start();
		
		for (int i = 1; i <=200; i++) {
			System.out.println("主线程:" + i);
			if (i == 10) {
				//合并
				t.join();
			}
		}
	}
}

public class MyThread extends Thread{

	@Override
	public void run() {
		for (int i = 1; i <= 200; i++) {
			System.out.println("子线程:" + i);
		}
	}
}

十三、线程的中断

使用MyThread中的flag属性去控制

1.方案一

public class Test01 {

	public static void main(String[] args) throws InterruptedException{
		
		MyThread t = new MyThread();
		t.start();
		
		Thread.sleep(3000);
		
		//立即中断线程
		//t.stop();//淘汰使用
		
		t.setFlag(false);
	}
}

public class MyThread extends Thread{

	private boolean flag = true;

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	@Override
	public void run() {
		while(flag){
			System.out.println("111");
			System.out.println("222");
			System.out.println("333");
			System.out.println("444");
	   }
	}
}

2.方案二

public class Test01 {

	public static void main(String[] args) throws InterruptedException{
		
		MyThread t = new MyThread();
		t.start();
		
		Thread.sleep(3000);
		
		//改变线程状态
		t.interrupt();
	}
}

public class MyThread extends Thread{

	@Override
	public void run() {

		Thread thread = Thread.currentThread();
		
		while (!thread.isInterrupted()) {//判断当前线程是否中断
			
			System.out.println("111");
			System.out.println("222");
			System.out.println("333");
			System.out.println("444");
			
		}
	}
}

十四、守护线程

含义:守护线程默默守护着前台线程,当所有前台线程都死亡时,守护线程就会自动死亡

注意:垃圾回收器就是守护线程

t.setDaemon(true);

public class Test01 {

	public static void main(String[] args) throws InterruptedException{
		
		MyThread t = new MyThread();
		t.setDaemon(true);
		t.start();
		
		for (int i = 1; i <=5; i++) {
			System.out.println("主线程:" + i);
			Thread.sleep(1000);
		}
	}
}

//做实验
//父类方法如果不抛异常,子类重写时就不能抛异常,必须try...catch...
class A{
	public void method(){}
}
class B extends A{
	
	@Override
	public void method(){
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

public class MyThread extends Thread{

	@Override
	public void run() {
		while (true) {
			System.out.println("守护线程正在守护着前台线程");
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

十五、线程局部变量(实现线程范围内的共享变量)

1.共享单个数据

public class Test01 {

	public static void main(String[] args) {
		
		//线程1
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				int i = 10;
				
				//存储数据
				Container.map.put(Thread.currentThread(),i);
				
				A a = new A();
				B b = new B();
				a.println();//线程1中的A类对象输出:10
				b.println();//线程1中的B类对象输出:10
			}
		},"线程1").start();
		
		//线程2
		new Thread(new Runnable() {
			@Override
			public void run() {
				int i  = 20;
				
				//存储数据
				Container.map.put(Thread.currentThread(),i);
				
				A a = new A();
				B b = new B();
				a.println();//线程2中的A类对象输出:20
				b.println();//线程2中的B类对象输出:20
				
			}
		},"线程2").start();
	}
}

import java.util.concurrent.ConcurrentHashMap;

public class Container {
	public static final ConcurrentHashMap<Thread, Integer> map = new ConcurrentHashMap<>();
}

public class A {

	public void println(){
		
		Thread thread = Thread.currentThread();
		Integer value = Container.map.get(thread);
		
		System.out.println(thread.getName() + "中的A类对象输出:" + value);
	}
}

public class B {

public void println(){
		
		Thread thread = Thread.currentThread();
		Integer value = Container.map.get(thread);
		
		System.out.println(thread.getName() + "中的B类对象输出:" + value);
	}
}

2.共享多个数据

public class Test01 {

	public static void main(String[] args) {
		
		//线程1
		new Thread(new Runnable() {
			@Override
			public void run() {
				
				Data data = new Data("xxx",10);
				//存储数据
				Container.map.put(Thread.currentThread(),data);
				
				A a = new A();
				B b = new B();
				a.println();//线程1中的A类对象输出:10
				b.println();//线程1中的B类对象输出:10
			}
		},"线程1").start();
		
		//线程2
		new Thread(new Runnable() {
			@Override
			public void run() {
				Data data = new Data("yyy",20);
				//存储数据
				Container.map.put(Thread.currentThread(),data);
				
				A a = new A();
				B b = new B();
				a.println();//线程2中的A类对象输出:20
				b.println();//线程2中的B类对象输出:20
			}
		},"线程2").start();
	}
}

import java.util.concurrent.ConcurrentHashMap;

public class Container {

	public static final ConcurrentHashMap<Thread, Data> map = new ConcurrentHashMap<>();
}

public class A {

	public void println(){
		
		Thread thread = Thread.currentThread();
		Data value = Container.map.get(thread);
		
		System.out.println(thread.getName() + "中的A类对象输出:" + value);
	}
}

public class B {

public void println(){
		
		Thread thread = Thread.currentThread();
		Data value = Container.map.get(thread);
		
		System.out.println(thread.getName() + "中的B类对象输出:" + value);
	}
}

3.使用ThreadLocal的技术

public class Test01 {

	public static void main(String[] args) {
		
		//线程1
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				Data data = Data.getInstance("xxx",10);
				//存储数据
				Container.local.set(data);
				
				A a = new A();
				B b = new B();
				a.println();//线程1中的A类对象输出:10
				b.println();//线程1中的B类对象输出:10
				
			}
		},"线程1").start();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				Data data = Data.getInstance("yyy",20);
				
				Container.local.set(data);
				
				A a = new A();
				B b = new B();
				a.println();//线程2中的A类对象输出:20
				b.println();//线程2中的B类对象输出:20
				
			}
		},"线程2").start();
	}
}

//容器类
public class Container {
	
	public static final ThreadLocal<Data> local = new ThreadLocal<>();
}

public class A {
	
    public void println(){
		
		Thread thread = Thread.currentThread();
		Data value = Container.local.get();
		
		System.out.println(thread.getName() + "中的A类对象输出:" + value);
		
	}
}

public class B {
	
public void println(){
		
		Thread thread = Thread.currentThread();
		Data value = Container.local.get();
		
		System.out.println(thread.getName() + "中的B类对象输出:" + value);
	}
}

十六、总结

1.进程 与 进程 的关系:独享内存空间和系统资源

2.线程 与 进程 的关系:有一个进程中至少包含一个线程

3.线程 与 线程 的关系:在同一个进程里,多个线程共享内存空间和系统资源

4.一个进程中包含多个线程,只有一个主线程

5.垃圾回收器是一个后台线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨霖先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值