每日一狗(田园犬西瓜瓜)

程序执行的整个过程叫做进程
僵尸进程:子进程完了,父进程没有把子进程占用的资源进程回收,这个子进程就是僵尸进程(必须解决,站着内啥不内啥,严令禁止,杜绝浪费)
孤儿进程:父进程比子进程先退出,他会被初始化进程init进程所收养,由init负责改进程的资源管理(占就占呗,反正还没跑完)
进程无法将CUP性能榨干,能让它闲着吗?不能够呀,聪明的开发人员由在进程之下划分了多个线程。
程序运行时,系统会先开一个进程,然后再自动开一个主线程,你的主方法就会在这个主线程中执行。
虽然说主线程和进程中的其他进程没啥不一样的,但是所谓的主线程main可以在执行完处理逻辑后调用System.exit()。exit会让整个进程over终止,那所有线程自然都会退出。
进程中的线程都是平级的,没有父子之分。
在大规模的计算时,cpu本身就忙着,在用多线程,cpu会将正在执行的程序相关数据进行存储,这是有时间代价的。
这时候就需要进行线性扩展,让两个三个多个计算机来帮忙!
缺点:上下文切换的开销
不能直接调用run方法,直接调用就是单线程干的事
执行过程不可重现 把握不住
package com.yang2;
public class Test01 {
public static void main(String[] args) {
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("左手重播"); // 阻塞200ms
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t2 = new MyThread();
t1.start();
t2.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("右手重播");
try {
Thread.sleep(200); // 阻塞200ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程启动时调用start()方法会默认调度执行其中的public void run() {}方法
可以看到用run执行的程序的线程和主方法是统一个线程
package com.yang2;
public class Test02 {
public static void main(String[] args) {
System.out.println(Thread.currentThread());
// Thread[main,5,main]
Thread t1 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("右手" + Thread.currentThread());
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t1.start(); // 右手Thread[Thread-0,5,main]
Thread t2 = new MyThread1();
t2.run(); // 左手Thread[main,5,main]
}
}
class MyThread1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("左手" + Thread.currentThread());
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
继承Thread(单根继承,使用受限)
实现Runnable接口
FutureTask可以有返回值的
使用线程池
Thread
public class Test1 {
public static void main(String[] args) {
System.out.println(Thread.currentThread()); //获取当前线程对象
//方法1.2
Thread t2=new Thread() {
@Override
public void run() {
for(int i=0;i<50;i++) {
System.out.println("右手慢动作重播"+Thread.currentThread());
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
// t2.run();
Thread t1=new MyThread3();
t1.start();
t2.start();
}
}
//方法1.1
class MyThread3 extends Thread{
@Override
public void run() {
for(int i=0;i<50;i++) {
System.out.println("左手一个慢动作"+Thread.currentThread());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Runnable
public class Test2 {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
t1.start();
// 方法2.2
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("中间手...."+Thread.currentThread());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// 方法2.3
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("右手...."+Thread.currentThread());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
//方法2.1
class MyRunnable implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("左手...."+Thread.currentThread());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
FutureTask
package com.yang2;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test06 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 为了获取返回值,所以需要使用FutureTask中提供的get方法
FutureTask<Integer>[] arr = new FutureTask[10];
for (int i = 1; i <= 10; i++) {
int begin = (i - 1) * 100 + 1;
int end = i * 100;
// 定义Callable的实现
Callable<Integer> c = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int res = 0;
for (int i = begin; i <= end; i++) {
res += i;
}
return res;
}
};
// 构建FutureTask对象,其中包含Callable对象
FutureTask<Integer> ft = new FutureTask<Integer>(c);
arr[i - 1] = ft;
// 启动线程,构建Thread对象时,要求参数类型为Runnable接口类型
// 线程执行时会自动调用run方法,而FutureTask中提供的run方法会调用Callable对象的call方法
new Thread(ft).start();
}
int res = 0;
for (FutureTask<Integer> tmp : arr) {
// main线程执行到这里时,会自动阻塞等待子线程tmp执行结束,执行结束后获取call方法的返回值
res += tmp.get();
}
System.out.println(res);
}
}
线程池
package com.yang2;
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;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test08 {
public static void main(String[] args) {
// 固定线程池
// ExecutorService es = Executors.newFixedThreadPool(3); // 就三个
// 缓存线程池
ExecutorService es = Executors.newCachedThreadPool(); // 这有十个
FutureTask<Integer>[] arr = new FutureTask[10];
for (int i = 1; i <= 10; i++) {
int begin = (i - 1) * 100 + 1;
int end = i * 100;
arr[i - 1] = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread());
int res = 0;
for (int i = begin; i <= end; i++) {
res += i;
}
return res;
}
});
es.submit(arr[i - 1]);
}
int res = 0;
for (Future<Integer> tmp : arr) {
try {
res += tmp.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
}
System.out.println(res);
}
}
想要将运算结果拿出来在计算就难受 了
package com.yang2;
public class Test04 {
public static void main(String[] args) throws InterruptedException {
MyRunnable04[] arr = new MyRunnable04[10];
for (int i = 1; i <= 10; i++) {
MyRunnable04 r = new MyRunnable04((i - 1) * 100 + 1, i * 100);
arr[i - 1] = r;
new Thread(r).start();
}
Thread.sleep(2000);
for (MyRunnable04 r : arr) {
System.out.println(r.getRes());
}
}
}
class MyRunnable04 implements Runnable {
private int begin, end, res = 0;
public MyRunnable04(int begin, int end) {
this.begin = begin;
this.end = end;
}
public int getRes() {
return res;
}
@Override
public void run() {
for (int i = begin; i <= end; i++) {
res += i;
}
}
}
package com.yang2;
public class Test05 {
static int sum = 0;
public static void main(String[] args) throws InterruptedException {
for (int i = 1; i <= 10; i++) {
int begin = (i - 1) * 100 + 1;
int end = i * 100;
new Thread(new Runnable() {
@Override
public void run() {
int res = 0;
for (int i = begin; i <= end; i++) {
res += i;
}
sum += res;
}
}).start();
}
Thread.sleep(5000);
System.out.println(sum);
}
}
OOM可能原因
核心线程->阻塞队列->工作线程->饱和策略/拒绝策略


核心线程永不回收(就是把已经存在的线程数量回收到核心线程数时就不回收了)
public ThreadPoolExecutor(等等){}
package com.yang2;
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;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test08 {
public static void main(String[] args) {
// ExecutorService es = Executors.newFixedThreadPool(3); // 就三个
ExecutorService es = Executors.newCachedThreadPool(); // 这有十个
FutureTask<Integer>[] arr = new FutureTask[10];
for (int i = 1; i <= 10; i++) {
int begin = (i - 1) * 100 + 1;
int end = i * 100;
arr[i - 1] = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread());
int res = 0;
for (int i = begin; i <= end; i++) {
res += i;
}
return res;
}
});
es.submit(arr[i - 1]);
}
int res = 0;
for (Future<Integer> tmp : arr) {
try {
res += tmp.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
}
System.out.println(res);
}
}
用一个池子来管理一堆资源对象,需要的时候你来我这个池子要,池子给你一个,用完了不要释放对象,你在还给我这个池子,你下次再用,我再来问你要。
公共接口:池子里的东西都间接或直接的实现该接口
interface IShape {
void draw();
}
实现类:池子里放的东西
class Circle implements IShape {
@Override
public void draw() {
System.out.println("这里是三角形");
}
}
调度管理类:要东西问这个类要,用完记得归还
class ObjectManager {
static IShape[] arr = new IShape[20];
static {
for (int i = 0; i < 20; i++) {
arr[i] = new Circle();
}
}
public static IShape getInstance() {
IShape res = null;
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] != null) {
res = arr[i];
arr[i] = null;
break;
}
}
return res;
}
public static void releaseInstance(IShape obj) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] == null) {
arr[i] = obj;
break;
}
}
}
}
测试类:有借有还再借不难,但是这个没用多线程,所以全都是第一个类
package com.yang2;
public class Test07 {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
IShape tmp = ObjectManager.getInstance();
System.out.println(tmp);
ObjectManager.releaseInstance(tmp);
}
}
}
打辅助的
当前进程中除了守护线程之外没线程了,守护线程这会就关了。
可以对线程组内的线程进行统一管理