进程和线程

进程和线程,第1张

进程:         是一段运行起来的程序

                        特点:

                                单核CPU在任意时间点都只能运行一个进程

                                宏观是并行,微观串行

线程:

        又称轻量级进程(Light Weight Process)

                程序中的一个顺序控制流程,同时也是CPU的基本调度单位  

                进程由多个线程组成,彼此完成不同的任务,交替执行,我们叫多线程     

进程和线程的区别:

        进程是 *** 作系统 资源分配的基本单位,而线程是CPU的基本调度单位

        一个程序运行后至少有一个进程

        一个进程可以包括多个线程,但是最少需要一个线程

        进程间不能共享数据段地址,但同进程的线程之间可以     

线程组成 

        CPU时间片: *** 作系统(OS)会为每个线程分配执行时间

        运行数据

                堆空间:储存线程需使用的对象,多个线程可以共享堆中的对象

                栈空间:储存线程所需要的局部变量,每个线程都有独立的栈

创建线程

          JAVA中创建线程主要有两种方法

                继承Thread类

                实现Runnable接口

继承Thread类

        步骤:

                编写类,继承Thread

                重写run方法

                创建线程对象

                调用start方法启动线程,(不能调用run方法)

package com.cs.test;

public class Test006 {
    public static void main(String[] args) {
        MyThread1 myThread1 = new MyThread1();
        //启动线程
        myThread1.start();

    }

}
//继承Thread类
class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            System.out.println("子线程"+i);
        }
    }
}

获取线程名称

        getName()

        Thread.currentThread().getName()

package com.cs.test;
public class Test006 {
    public static void main(String[] args) {
        MyThread1 myThread1 = new MyThread1();
       myThread1.start();
    }

}
class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            System.out.println(Thread.currentThread().getName()+"吃饭了");
        }
    }
}

案例:

实现四个窗口卖火车票

package com.cs.test;
public class Test006 {
    public static void main(String[] args) {
        MyThread1 myThread1 = new MyThread1();
        MyThread1 myThread2 = new MyThread1();
        MyThread1 myThread3 = new MyThread1();
        MyThread1 myThread4 = new MyThread1();
        myThread1.start();
        myThread2.start();
        myThread3.start();
        myThread4.start();
    }

}
class MyThread1 extends Thread{
    private static int count=200;
    @Override
    public void run() {
        while (true){
            if (count<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"卖了第"+count+"张票");
            count--;
        }
    }
}
实现Runnable接口:

        步骤

                编写类实现Runnable接口,并实现run方法

                创建Runnable类实现对象

                创建线程对象,传递实现类对象

                启动线程     


class MyThread1 implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() +);
    
        }
    
}

 

package com.cs.test;
public class Test006 {
    public static void main(String[] args) {
    //创建对象
        MyThread1 myThread1 = new MyThread1();
        Thread thread = new Thread(myThread1,"我的线程");
        thread.start();
        for(int i=0;i<50;i++) {
            System.out.println("main............"+i);
        }
    }

}
线程状态:

                新建,就绪,运行,终止

        常用方法:

                Thread.sleep:让线程进入休眠

                Thread.yield;当前线程主动放弃时间片,回到就绪状态,竞争下一个时间片

                Thread.join:允许线程到其他线程中去

                Thread.setPriority(int):线程优先级为1~10,默认5.,优先级越高,获得CPU的几率越大

                Thread.setDaemon(blooen):设置为守护线程有两种用户线程(前台线程),守护线程(后台线程)

        线程状态(等待)

                新建,就绪,运行,等待,终止

线程安全

               线程不安全:

                        当多线程并发访问临界资源时,如果破坏原子 *** 作,可能会造成数据不一致

                        临界资源:共享资源,一次允许一个线程使用,才可以保证其正确性

                        原子 *** 作:不可分割的多步 *** 作,被视作一个整体,其顺序和步骤都不可以被打乱或缺缺失

public class ThreadSafe {
	private static int index=0;
	public static void main(String[] args)  throws Exception{
		//创建数组
		String[] s=new String[5];
		//创建两个 *** 作
		Runnable runnableA=new Runnable() {
			
			@Override
			public void run() {
				//同步代码块
				synchronized (s) {
					s[index]="hello";
					index++;
				}
				
			}
		};
		Runnable runnableB=new Runnable() {
			
			@Override
			public void run() {
				synchronized (s) {
					s[index]="world";
					index++;
				}
				
			}
		};
		
		//创建两个线程对象
		Thread a=new Thread(runnableA,"A");
		Thread b=new Thread(runnableB,"B");
		a.start();
		b.start();
		
		a.join();//加入线程
		b.join();//加入线程
		
		System.out.println(Arrays.toString(s));
		
	}
同步代码块

        语法

                synchronized(临界资源对象){

//对临界资源对象加锁

//代码(原子 *** 作)

}

public class Ticket implements Runnable{
	
	private int ticket=100;
	//创建锁
	//private Object obj=new Object();
	
	@Override
	public void run() {
		
		while(true) {
			synchronized (this) {//this ---当前对象
				if(ticket<=0) {
					break;
				}
				System.out.println(Thread.currentThread().getName()+"卖了第"+ticket+"票");
				ticket--;
			}
			
		}
	}
	
}
线程状态(阻塞)

        新建,就绪,运行,阻塞,终止

 同步方法:

        语法: synchronized 返回值类型 方法名称(形参列表){

        //对当前对象(this)加锁 // 代码(原子 *** 作)

        }

同步规则:

        只有在调用包含同步代码块的方法,或者同步方法时,才需要对象额锁标记

         如调用不包含同步代码块的方法,或普通方法时,就不需要锁标记,可以直接调用 

JDK中线程安全的类:

  • StringBuffer

  • Vector

  • Hashtable 以上类中的公开方法,均为synchonized修饰的同步方法。

线程池:

           为什么需要线程池

                如果有非常多的任务需要完成,且每个线程的执行时间不会太长,这样频繁的创造和销毁线程,        

                这样频繁的创建和销毁线程,消耗性能比较多,有了线程池就不用创建更多的线程了,毕竟线程可以重用了

        线程池原理:
                线程池用维护着一个队列,队列中保存这处于等待状态的线程,不用每次都创建新线程

        线程池API:

                Executor:线程池顶级接口

                ExecutorService:线程池接口,可通过submit(Runnable task)提交任务代码

                Executor工厂类:通过此类可获得一个线程池

                newFixedThreadPool(int nThreads):获取固定数量的线程池,参数:指定线程池中线程数量        

                newCachedThreadPool():获得动态数量的线程池,如不够就创建新的,无上限

                newSingThreadExecutor()创建单个线程的线程池,只有一个线程

                newScheduledThreadPool():创建固定大小的线程池,可以延时或定时执行任务

public class TestThreadPool {
	public static void main(String[] args) {
		//1.1创建固定线程个数的线程池
		//ExecutorService es=Executors.newFixedThreadPool(4);
		//1.2创建缓存线程池,线程个数由任务个数决定
		ExecutorService es=Executors.newCachedThreadPool();
		//1.3创建单线程线程池
		//Executors.newSingleThreadExecutor();
		//1.4创建调度线程池  调度:周期、定时执行
		//Executors.newScheduledThreadPool(corePoolSize)
		Executors.newScheduledThreadPool(3);
		//2创建任务
		Runnable runnable=new Runnable() {
			private int ticket=100;
			@Override
			public void run() {
				while(true) {
					if(ticket<=0) {
						break;
					}
					System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票");
					ticket--;
				}
			}
		};
		//3提交任务
		for(int i=0;i<5;i++) {
			es.submit(runnable);
		}
		//4关闭线程池
		es.shutdown();//等待所有任务执行完毕 然后关闭线程池,不接受新任务。
	}
}
Callable接口:
​​​​​​​        
public class TestCallable {
	public static void main(String[] args) throws Exception{
		//功能需求:使用Callable实现1-100和
		//1创建Callable对象
		Callable callable=new Callable() {
			@Override
			public Integer call() throws Exception {
				System.out.println(Thread.currentThread().getName()+"开始计算");
				int sum=0;
				for(int i=1;i<=100;i++) {
					sum+=i;
					Thread.sleep(100);
				}
				return sum;
			}
		};
		//2把Callable对象 转成可执行任务
		FutureTask task=new FutureTask<>(callable);
		
		//3创建线程
		Thread thread=new Thread(task);
		
		//4启动线程
		thread.start();
		
		//5获取结果(等待call执行完毕,才会返回)
		Integer sum=task.get();
		System.out.println("结果是:"+sum);
	}
}

Runnable接口和Callable接口的区别

        Callable接口中Call方法有返回值,Runnable接口中run方法没有返回值

        Callable接口中Call方法有声明异常,Runnable接口中run方法没有声明异常

Future接口

        Future接口表示将要执行完任务的结果

        get()阻塞形式等待Future中的异步处理结束call()的返回值

public class TestFuture {
	public static void main(String[] args) throws Exception{
		//1创建线程池
		ExecutorService es=Executors.newFixedThreadPool(1);
		//2提交任务 Future:表示将要执行完任务的结果
		Future future=es.submit(new Callable() {

			@Override
			public Integer call() throws Exception {
				System.out.println(Thread.currentThread().getName()+"开始计算");
				int sum=0;
				for(int i=1;i<=100;i++) {
					sum+=i;
					Thread.sleep(10);
				}
				return sum;
			}
		});
		
		//3获取任务结果,等待任务执行完毕才会返回.

		System.out.println(future.get());
		
		//4关闭线程池
		es.shutdown();
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/917249.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存