1.进程:正在运行中的程序–动态的
程序:静态的数据与指令的集合–静态的
2.进程的特点:
独立性:进程有自己独立的空间,可以独立运行,多个进程互不影响
动态性:进程加入了时间的概念有生命周期和不同的状态
并发性:单个CPU可以处理多个进程,进程一起运行互不影响
3.并行与并发:
并发:多个进程抢占CPU
并行:多个进程都有自己的CPU进行处理,没有发生抢占的现象
TIPS:在高并发场景下实现高可用HA
4.线程:线程是OS可以进行运算调度的最小单位
一个进程可以开启多个线程,如果一个进程只有一个线程-单线程程序
多线程拓展了多进程,也就是一个进程可以干多件事
每个线程拥有自己独立的内存空间,多个线程之间也存在共享数据
5.宏观层面上,多个进程/进程看起来是同时运行的
微观层面上,一个CPU同一时刻只能处理一件事
至于哪个时刻执行哪个线程,取决于OS底层的算法(FCFS/SJS…)
注意:线程什么时候会执行?
OS选中它,给它分配时间片(允许OS执行当前线程的一段时间)
没有时间片的线程是挂起(暂停/冻结)的状态,等待再次被分配时间片才能
6.线程的几种状态和状态之间的转换
新建 就绪 执行 阻塞 结束状态
7.我们new线程对象时对应着的是线程的新建状态、
我们调用start()才会把线程变为就绪状态
8.多线程编程实现方案:
1)extends Thread
例题:
package cn.tedu.thread;
/**多线程的实现方式一*/
/**线程的随机性:多个线程对象执行的结果是不可控的,因为cpu会调度处理
* 结果具有随机性,至于哪个时间片让哪个线程执行,时间片有多长,我们都控制不了*/
public class TestThread {
public static void main(String[] args) {
//4.创建线程对象进行测试
MyThread t=new MyThread();//3.new 对应的线程状态是新建状态
//5.模拟多线程,再创建线程对象
MyThread t2=new MyThread();
MyThread t3=new MyThread();
MyThread t4=new MyThread();
MyThread t5=new MyThread("小灰灰");
//t2.run();//普通方法,不会出现多线程的效果
t.start();//start()才会把线程加入就绪队列,以多线程的方式运行
t2.start();
t3.start();
t4.start();
t5.start();
}
}
//1.定义自定义多线程类
/**方式一:extends Thread*/
class MyThread extends Thread{
public MyThread(){
}
public MyThread(String name){
//子类构造方法触发父类的构造方法给线程对象起名字
super(name);
}
//2.1线程中的业务必须写在run()里,我们不执行父类的run(),有自己的业务
public void run(){
//3.完成自己的业务:输出十次当前正在执行的线程名称
for(int i=0;i<10;i++){
/**2.getName()可以获取当前正在执行的线程名称
* 由于是从父类继承过来的方法,所以可以通过方法名直接使用*/
System.out.println(i+"="+getName());
}
}
}
2)implements Runnable
例题:
package cn.tedu.thread;
public class TestHtread2 {
public static void main(String[] args) {
MyRunnable target=new MyRunnable();
Thread t1=new Thread(target);
Thread t2=new Thread(target);
Thread t3=new Thread(target);
Thread t4=new Thread(target);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class MyRunnable implements Runnable{
public void run(){
for(int i=0;i<10;i++){
System.out.println(i+"="+Thread.currentThread().getName());
}
}
}
- 线程池
package cn.tedu.thread;
import java.lang.reflect.Executable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestExecute {
public static void main(String[] args) {
run target=new run();
ExecutorService pool= Executors.newFixedThreadPool(5);
for(int i=0;i<5;i++){
pool.execute(target);
}
}
}
class run implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getName());
}
}
9.数据安全问题解决方案
1)出现的3个条件
2)锁的唯一性
例题一:
package cn.tedu.ticket;
public class TicketThreadv2 {
public static void main(String[] args) {
Tickets2 t1=new Tickets2();
Tickets2 t2=new Tickets2();
Tickets2 t3=new Tickets2();
Tickets2 t4=new Tickets2();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Tickets2 extends Thread{
static int tickets=100;
Object o =new Object();
public void run(){
while(true){
synchronized (Tickets2.class){
if(tickets>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//设置主动休眠,制造阻塞,暴露数据安全隐患
System.out.println(getName()+"="+tickets--);}
if(tickets<=0)break;
}}}
}
例题二:
package cn.tedu.ticket;
import javafx.beans.binding.ObjectExpression;
import static java.lang.Thread.sleep;
public class IcketRunableV2 {
public static void main(String[] args) {
TicketRT target=new TicketRT();
Thread t1=new Thread(target);
Thread t2=new Thread(target);
Thread t3=new Thread(target);
Thread t4=new Thread(target);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class TicketRT implements Runnable{
int tickets=100;
Object o=new Object();
public void run(){
while(true){
synchronized(o){//解决重复问题
if(tickets>0){//解决超卖问题
try {//给程序主动设置休眠,制造阻塞,暴露数据安全隐患
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"="+tickets--);}
if(tickets<=0)break;
}}
}
}