一,程序,进程,线程
* 1.程序:指令集,静态概念;
* 2.进程:操作系统 调度程序 动态概念
* 3.线程:在进程内多条执行路径
* main方法和gc和异常
* 程序是一个静态的概念;进程:是一个动态的概念;
* 进程是程序的一次动态执行过程,占用特定的地址空间;
* 每个进程都是独立的
* 由3部分组成cpu data code;
* 缺点:内存的浪费,cpu的负担
*线程:是进程中一个“单一的连续控制流程”
*线程又被称为轻量级进程;一个进程可拥有多个并行的线程;一个进程中的线程共享相同的内存单元/内存地址空间(因此会
*造成并发问题),
*可以访问相同的变量和对象,而且他们从同一堆中分配对象;
进程:
* 作为资源分配的单位;
* 每个进程都有独立的代码和数据空间,进程间的切换会有较大的开销;
* 在操作系统中能同时运行多个多个任务;
* 系统在运行的时候为每个进程分配不同的内存区域;
* 没有线程的进程可以看成是多线程,如果一个进程内拥有多个线程,则执行过程不是一条线的,
* 而是多条线程共同完成的;
线程:
* 线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器,
* 线程切换的开销较小;
* 在同一应用程序中有多个顺序流同时执行;
* 除了cpu之外,不会为线程分配内存,线程所使用的资源是它所属进程的资源,线程组只能共享资源,
* 线程是进程的一部分,所以线程有的时候被称为是轻权进程或者轻量级进程;
java实现多线程(一)
* 在Java中负责线程的功能是Java.lang.Thread这个类; 可以通过创建Thread的实例来创建新的线程;
* 每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run称为线程体;
* 通过调用thread类的start方法来启动一个线程;(java是单继承多实现,此方法不被建议)
public class Thread02 {
/**
* 模拟龟兔赛跑 创建多线程 继承thread +重写run 使用线程:创建子类对象+对象的start方法
*/
public static void main(String[] args) {
Rabbit r = new Rabbit();
r.start();
Tortoise t=new Tortoise();
t.start();
}
}
public class Rabbit extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("兔子跑了" + i + "步");
}
}
}
public class Tortoise extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("乌龟" + i + "步");
}
}
}
二)使用Runnable接口
* 类实现runnable接口加上实现run方法,真实角色类, 推荐使用第二种: (1)避免单继承 (2)便于共享资源 (不能抛出异常,没有返回值);
public class Thread03 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("一边敲代码");
}
}
}
public class Thread03App {
public static void main(String[] args) {
Thread03 t = new Thread03();
Thread proxy = new Thread(t);
proxy.start();
for (int i = 0; i < 1000; i++) {
System.out.println("一边聊qq");
}
}
}
* java实现多线程(三)
* 使用Callable接口(Java.util.Concurrent)创建线程,优点:可以获取返回值
package Tread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Thread04 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建线程
ExecutorService ser = Executors.newFixedThreadPool(2);
Race tor = new Race("tor", 1000);
Race rabbit = new Race("rabbit", 500);
//获取值
Future<Integer> res=ser.submit(tor);
Future<Integer> res2=ser.submit(rabbit);
Thread.sleep(2000);
// 停止循环
tor.setFlag(false);
rabbit.setFlag(false);
Integer num= res.get();
Integer num2 = res2.get();
System.out.println("乌龟跑了"+num);
System.out.println("兔子跑了"+num2);
//停止服务
ser.shutdownNow();
}
}
class Race implements Callable<Integer> {
private String name;
private int time;
private int step = 0;
boolean flag = true;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public Race(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public Race(String name, int time) {
super();
this.name = name;
this.time = time;
}
public Race() {
super();
}
@Override
public Integer call() throws Exception {
while (flag) {
Thread.sleep(time);
step++;
}
return step;
}
}
* Callable接口和Future接口
* Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他现场执行的 任务
* Callable接口和Runnable接口有几点不同:
* (1)Callable接口规定的方法是Call,而Runnable规定的方法是Run;
* (2)call方法可以抛出异常,Runnable方法不行;
* (3)Callable的任务执行后可返回值,运行Callable任务可拿到一个Future返回值,而Runnable的任务是没有返回值的
* Future表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果,通过Future对象可了解
* 任务执行情况,可取消任务的执行,还可获取执行的结果
* 缺点:繁琐
* 思路:
1)创建Callable实现类+重写call;
* 2)借助执行调度服务ExecuteService,获取Future对象 ExecuteService
ser=Executors.newFixedThreadPool(2); Future result=ser.submit(实现类对象);
* 3)获取值:result.get;
4)停 止服务:ser.shutdownnow();