Java线程基础

  1. 进程 和 线程
    进程就是指代码/算法在特定的数据集合上一次执行/运行的活动
    也是系统进行资源分配和调度的基本单位。
    线程则是进程的一个执行任务/单元,是进程中的一个实体。
    一个进程中至少有一个线程,
    进程中的多个线程是共享进程的资源的

  2. 操作系统资源分配和调度
    操作系统在分配资源时是把资源分配给进程的,
    但CPU资源比较特殊,是分派到线程级别的,
    因为真正占用CPU运行的是线程,

将CPU的使用时间,划分为一个一个的时间片,
根据时间片调度分派给线程,只有线程获得CPU的时间片,
才可占用CPU运行代码。
假设CPU是单核的,同一个时间点,只有一个线程在运行。
细节微观的看,线程是顺序执行;
从人类角度宏观的看,是并行的:听歌、写文档等

  1. 进程的内存空间
    进程中有多个线程,多个线程共享进程中的堆和方法区资源,
    同时每个线程有自己的栈和程序计数器。

栈空间,用于存放线程执行中的局部变量,
这些局部变量,是当前线程私有的,其它线程也访问不了。
另外栈还用来存放线程的调用栈帧。

程序计数器,用来记录线程当前要执行的指令地址。
其实是为了记录让出CPU时间片时执行的地址

堆是进程中最大的一块内存空间,被进程中所有线程共享。
里面存放的是使用new创建的对象实例。

方法区,存放的是进程中要执行的代码,被线程共享

  1. Java中的线程
    Java中使用Thread类,表示一个线程
    JVM启动会开启一个进程java.exe
    在jvm内部,运行java程序,执行多个线程

线程是一个执行任务单元;
Java中可以使用Thread类表示线程。

建立线程的方法:
1.

package day27_0324;


/**
 * 1. 程序运行后,会产生进程,进程中至少有一个线程(即:主线程)
 * 2. 线程是一个执行任务/执行单元
 * 3. Java使用Thread类表示线程
 * 	class Thread implements Runnable
 * 4. JVM启动后,会在主线程中执行main方法中的代码;
 * 	  main线程中,创建启动了一个新的线程MyThread mt,不停地打印输出
 * 	  main线程接下来,继续向下执行代码,不停地打印输出
 * 	此时,在java进程中,有两个线程同时在运行!!
 * 
 */
public class ThreadDemo01 {
	public static void main(String[] args) {
		System.out.println("在主线程中,执行代码。"); //debug观察 Thread-main
		
		MyThread mt = new MyThread();
		mt.start(); //启动线程
			// 在进程分配空间,等待CPU调度
			// 当获得CPU的时间片时,才调用执行run()方法中的指令
		
		//while(true) {
		for (int i = 0; i < 30; i++) {
			System.out.println("我是 main 主线程"); //debug观察两个线程同时运行
			try {
				Thread.sleep(300); //让线程休眠一会,300毫秒,慢下来便于观察
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("主线程代码执行完毕!");
	}
}

/**
 * 创建一个自定义的线程,定义类型继承Thread即可
 * 将需要执行的任务,添加到类中run()方法中。
 * 当run()方法中的任务代码执行完毕后,该线程就结束了!
 */
class MyThread extends Thread {
	
	//run()方法没有返回值,也不能抛出异常
	@Override
	public void run() {
		System.out.println("我是一个新的线程!");
		System.out.println("当前对象:" + this);
		//while(true) {
		for (int i = 0; i < 20; i++) {
			System.out.println("我是:" + this);
			try {
				Thread.sleep(300); //让线程休眠一会,300毫秒,慢下来便于观察
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("新的线程执行结束!");
	}
}





package day27_0324;

/**
 * 借助Runnable接口,创建任务,传入到Thread(runnable)构造器中创建线程
 * 
 */
public class ThreadDemo02 {
	public static void main(String[] args) {
		RunnableTask task = new RunnableTask();
		Thread t = new Thread(task);
		t.start();
		
		System.out.println("主线程结束。"); //debug观察
	}
}
// 创建一个可执行的任务
class RunnableTask implements Runnable{
	@Override
	public void run() {
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("我是执行任务!");
	}
}

3.(不常用)

package day27_0324;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/** 了解即可
 * 1. JDK5.0中,引入了专门处理并发线程的包:
 * 		java.util.concurrent
 * 2. 在包中提供了新的可执行任务类:
 * 		Callable接口,接口中的方法是:
 * 			V call() throws Exception;
 * 			可返回结果,可抛出异常
 *		Runnable接口中的方法是:
 *			void run();
 *			没有返回结果,不能抛出异常
 */
public class ThreadDemo03 {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		MyCallable mc = new MyCallable();			//可被调用的对象,封装了计算逻辑
		FutureTask<String> task = new FutureTask(mc); //创建将要被执行的任务
		Thread t = new Thread(task);
		t.start();
		
		//获得线程执行的结果
		String result = task.get();
		System.out.println("线程执行的结果:" + result);
	}
}
//创建一个可被调用的自定义类
class MyCallable implements Callable<String> {
	@Override
	public String call() throws Exception {
		System.out.println("在新线程中,开始执行计算任务...");
		return "Smith";
	}
}

线程相关小方法

```java
package day27_0324;

/**
 * 线程中常用的API
 */
public class ThreadDemo04 {
	public static void main(String[] args) {
		
		//获得当前代码运行时,所在的线程
		Thread currThread = Thread.currentThread();
		System.out.println("运行当前代码的线程是:" + currThread.toString());
		System.out.println("运行当前代码的线程的ID:" + currThread.getId());
		System.out.println("运行当前代码的线程名是:" + currThread.getName());
		System.out.println("运行当前代码的线程所在线程组的名字:"
									+ currThread.getThreadGroup().getName());
		System.out.println("运行当前代码的线程的优先级是:" + 
												currThread.getPriority());
		System.out.println("运行当前代码的线程是守护线程吗:" + 
												currThread.isDaemon());
		
		
		// 使用匿名内部类写法,创建一个线程对象
		Thread t = new Thread() {
			@Override
			public void run() {
				//获得当前代码运行时,所在的线程
				Thread currThread = Thread.currentThread();
				System.out.println("运行当前代码的线程是:" + currThread.toString());
				System.out.println("运行当前代码的线程的ID:" + currThread.getId());
				System.out.println("运行当前代码的线程名是:" + currThread.getName());
				System.out.println("运行当前代码的线程所在线程组的名字:" + currThread.getThreadGroup().getName());
				System.out.println("运行当前代码的线程的优先级是:" + currThread.getPriority());
				System.out.println("运行当前代码的线程是守护线程吗:" + currThread.isDaemon());
			}
		};
		t.start();
		
		//再创建一个线程
		new Thread(new Runnable() {
			@Override
			public void run() {
				//获得当前代码运行时,所在的线程
				Thread currThread = Thread.currentThread();
				System.out.println("运行当前代码的线程是:" + currThread.toString());
				System.out.println("运行当前代码的线程的ID:" + currThread.getId());
				System.out.println("运行当前代码的线程名是:" + currThread.getName());
				System.out.println("运行当前代码的线程所在线程组的名字:" + currThread.getThreadGroup().getName());
				System.out.println("运行当前代码的线程的优先级是:" + currThread.getPriority());
				System.out.println("运行当前代码的线程是守护线程吗:" + currThread.isDaemon());
			}
		}, "第3个线程").start();
		
		
		
		System.out.println("线程的状态:" + currThread.getState());
		System.out.println("线程是活动的吗?" + currThread.isAlive());
	}
}


线程优先级控制

```java
package day27_0324;



/**
 * 线程的优先级
 * 1. 线程执行的前后顺序,是由多种因素决定的
 * 		项目实战时,不要去设置线程的优先级
 * 2. 线程被分配时间片的时机,以及时间的长短,
 * 		由系统调度来分配决定的,代码无法直接干涉
 * 3. 线程优先级,默认是:5
 * 	  线程优先级从小到大是:1~10
 */
public class ThreadDemo05 {
	public static void main(String[] args) {
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 1000; i++) {
					System.out.println(Thread.currentThread());
				}
			}
		}, "优先级为1的线程,最低优先级");
		t1.setPriority(1);
		
		Thread t5 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 1000; i++) {
					System.out.println(Thread.currentThread());
				}
			}
		}, "优先级为5的线程");
		
		Thread t10 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 1000; i++) {
					System.out.println(Thread.currentThread());
				}
			}
		}, "优先级为10的线程,最高优先级");
		t10.setPriority(10);
		
		t1.start();
		t5.start();
		t10.start();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值