我是靠谱客的博主 小巧纸鹤,最近开发中收集的这篇文章主要介绍进程和线程进程:        是一段运行起来的程序线程:进程和线程的区别:线程组成 创建线程实现Runnable接口:线程状态:线程安全同步代码块线程状态(阻塞) 同步方法:线程池:Callable接口: ​​​​​​​        ,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

进程:

        是一段运行起来的程序

                        特点:

                                单核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<Integer> callable=new Callable<Integer>() {
@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<Integer> 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<Integer> future=es.submit(new Callable<Integer>() {
@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();
}
}

最后

以上就是小巧纸鹤为你收集整理的进程和线程进程:        是一段运行起来的程序线程:进程和线程的区别:线程组成 创建线程实现Runnable接口:线程状态:线程安全同步代码块线程状态(阻塞) 同步方法:线程池:Callable接口: ​​​​​​​        的全部内容,希望文章能够帮你解决进程和线程进程:        是一段运行起来的程序线程:进程和线程的区别:线程组成 创建线程实现Runnable接口:线程状态:线程安全同步代码块线程状态(阻塞) 同步方法:线程池:Callable接口: ​​​​​​​        所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部