进程
进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能
线程
线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序
程序
程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
主线程
jvm启动后,必然有一个执行路径(线程)从main方法开始的,一直执行到main方法结束,这个线程在java中称之为主线程。
进程调度策略
java主要用的是抢占式调度
进程调度的方式参考进程调度策略
创建线程的方法(四种)
1.匿名代码块
package com.it.threads;
public class Demo2 {
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
for (int i = 0; i <1000 ; i++) {
System.out.println(Thread.currentThread().getName()+"---===>"+i);
}
}
}.start();
System.out.println("-----------main over--------------");
}
}
2.继承Thread类
package com.it.threads;
/**
* 创建线程的步骤: 1 定义一个类继承 Thread。
* 2 重写 run 方法。
* 3 创建子类对象,就是创建线程对象。
* 4 调用 start 方法,开启线程并让线程执行,
* 同时还会告诉 jvm 去调用 run 方法。
* @version: $
*/
public class ThreadA extends Thread {
/**
* 线程的任务写在run方法中
*/
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
//设置线程的名字
threadA.setName("得力");
threadA.setPriority(10);
//设置线程的优先级
ThreadA threadA1 = new ThreadA();
//设置线程的名字
threadA1.setName("得力1");
threadA1.setPriority(Thread.MIN_PRIORITY);
threadA1.start();
threadA.start();
System.out.println(threadA.getPriority());
System.out.println(threadA1.getPriority());
}
}
3.实现Runnable接口
package com.it.threads;
/**
* 1、定义类实现 Runnable 接口。
* 2、覆盖接口中的 run 方法。。
* 3、创建 Thread 类的对象
* 4、将 Runnable 接口的子类对象作为参数传递给 Thread 类的构造函数。
* 5、调用 Thread 类的 start 方法开启线程。
* @version: $
*/
public class ThreadB implements Runnable {
@Override
public void run() {
for (int i = 0; i <1000 ; i++) {
System.out.println(Thread.currentThread().getName()+"---->"+i);
}
}
public static void main(String[] args) {
ThreadB threadB = new ThreadB();
Thread thread1 = new Thread(threadB,"aa");
Thread thread2 = new Thread(threadB,"bb1");
//启动线程
thread1.start();
thread2.start();
}
}
4.线程池
线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
实现线程池分为两种
(1)实现Runnable
创建一个线程
package com.it.threadpool;
//方式一 实现Runnable接口
public class ThreadRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i <2; i++) {
System.out.println(Thread.currentThread().getName()+i+"进入电影院");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i+"离开电影院");
}
}
}
创建线程池
package com.it.threadpool;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
* 创建线程池对象
创建Runnable接口子类对象
提交Runnable接口子类对象
关闭线程池
* */
public class ThreadRunnablePool {
public static void main(String[] args) {
//创建线程池对象 线程个数 Executors:线程池创建工厂类 ExecutorService:线程池类
ExecutorService executorService = Executors.newFixedThreadPool(5);
//创建Runnable实例对象
ThreadRunnable threadRunnable = new ThreadRunnable();
//从线程池中获取线程对象,然后调用run()
executorService.submit(threadRunnable);
executorService.submit(threadRunnable);
executorService.submit(threadRunnable);
executorService.shutdown();
}
}
(2)实现Callable接口
创建线程
package com.it.threadpool;
import java.util.concurrent.Callable;
public class ThreadCallable implements Callable {
@Override
public Object call() throws Exception {
System.out.println("我要一个教练:call");
Thread.sleep(2000);
System.out.println("教练来了: " +Thread.currentThread().getName());
System.out.println("教我游泳,交完后,教练回到了游泳池");
return null;
}
}
创建线程池
package com.it.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadCallablePool {
public static void main(String[] args) {
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(2);
//生成Callable对象
ThreadCallable threadCallable=new ThreadCallable();
//从线程池中获取线程对象,然后调用run()
service.submit(threadCallable);
service.submit(threadCallable);
service.submit(threadCallable);
service.shutdown();
}
}
这两种方式的区别如下:
Callable定义的方法是call,而Runnable定义的方法是run。
Callable的call方法可以有返回值,而Runnable的run方法不能有返回值,这是核心区别。
Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。
举一个例子说明
创建一个线程用来求和
package com.it.threadpool;
import java.util.concurrent.Callable;
public class ThreadSum implements Callable<Integer> {
int x;
int y;
public ThreadSum(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public Integer call() throws Exception {
return x+y;
}
}
创建线程池
package com.it.threadpool;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadSumPool {
public static void main(String[] args) {
ExecutorService executorService= Executors.newFixedThreadPool(5);
//Future用来接收call方法的返回值
Future future1=executorService.submit(new ThreadSum(200,500));
Future future2=executorService.submit(new ThreadSum(100,500));
Future future3= executorService.submit(new ThreadSum(200,600));
try {
//get()方法用来获取返回值
System.out.println(future1.get());
System.out.println(future2.get());
System.out.println(future3.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}