进程和线程以及多线程

                                                        进程和线程以及多线程

1.什么是进程?

  进程:应用程序的执行实例,有独立的内存空间和系统资源,操作系统支持多进程并发运行。

  线程:进程中执行运算的最小单位(对应进程某一条执行的单元),也是CPU调度和分派的基本单位,真正在CPU上运行的线程。

   一个进程里可以有多个线程,我们称之为多线程。每个线程之间也是并发的。

   一个线程必须有一个父的进程。

   多个线程之间,我也可以让你个线程去创建和删除另外一个线程。所以,我们编程过程中,要防止线程间的相互调度

   多个线程共性进程的系统资源

   每一个进程都至少要有一个主线程,类似于下面代码中的main  它是程序的人口,也就是下面我定义的线程的主线程

线程之间是相互抢占资源  并发执行的

线程:系统线程  、 用户级的线程

2.如何创建一个线程

Java中创建线程的两种方式:

继承:java.lang.Thread类

实现java.lang.Runnable接口

示例如下:

MyThread类是自定的线程类,继承了Thread类

package cn.happy.thread;

public class MyThread extends Thread {
    private int count=0;
    //重写Thread类的run()方法
    @Override
    public void run() {
       while(count<100){
           System.out.println(count);
           count++;
       }
    }
    

}

下面再测试类中测试自定义的线程

package cn.happy.thread;

public class MyThreadText {
    public static void main(String[] args) {
        MyThread thread1=new MyThread();
        //程序员调用用start(),而不是run()方法  下面会讲解两者的区别
        thread1.start();
    }
}

下面进行讲解第二种实现Runnable接口来自定义线程的方法,以及线程的调用

自定义的实现Runnable接口的MyThread2类

package cn.happy.thread;

public class MyThread2 implements Runnable{
    private int count=0;
    @Override
    public void run() {
          while(count<100){
               System.out.println(count);
               count++;
           }
        
    }

}

调用线程

package cn.happy.thread;

public class MyThreadText {
    public static void main(String[] args) {
        //MyThread thread1=new MyThread();
        //程序员调用用start(),而不是run()方法  下面会讲解两者的区别
        //thread1.start();
        
        
        //创建了一个Runnable对象,还不是一个线程
        MyThread2 thread2=new MyThread2();
        //做为Thread构造方法的参数传入,构建一个线程
         Thread t1=new Thread(thread2);
         //线程启动
         t1.start();
    }
}

上述两种方式各有优劣:

1。继承可以减少代码量

2.java中继承具有单根性,就不能再让自定义的类去继承其他的类,这时候我们就用到了实现Runnable的方式

3.使用同一个Runnable对象构造的Thread线程对象共享Runnable的资源,而Thread类不同

对上面的代码做一些修正  就会说明另外一个知识点

MyThread2

package cn.happy.thread;

public class MyThread2 implements Runnable{
    private int count=0;
    @Override
    public void run() {
//          while(count<100){
//               System.out.println(count);
//               count++;
//           }
        count++;
        System.out.println(count);
    }

}

测试类

package cn.happy.thread;

public class MyThreadText {
    public static void main(String[] args) {

        //创建了一个Runnable对象,还不是一个线程
        MyThread2 thread2=new MyThread2();
        //做为Thread构造方法的参数传入,构建一个线程
         Thread t1=new Thread(thread2);
         
         Thread t2=new Thread(thread2);
         //线程启动
         t1.start();
         t2.start();
         }
}

运行结果为

上述运行结果说明一个问题

我们用Runnable对象构造的Thread线程对象,多个线程如果使用同一个Runnable对象去构造的,那么他们共享Runnable对象的一些资源(j及共享了同一个count属性)

使用线程的步骤:

1.定义线程

2.创建一个线程对象

3.启动线程  用start()方法 而非run()方法  

4.终止线程(1.run()执行完毕  2.在执行run()方法是发生了异常,而对于这些异常我们没有去捕获,也会强制终止进程)

start()和run()的区别

 start() 1.启动了一个线程  2.调用了线程的run()

如果直接调用run(),则相当于之启动了一个普通方法。

二、线程的生命周期:

包括四个状态:新生状态、可运行状态、阻塞状态和死亡状态

阻塞:把一个线程占有的CPU资源释放出来,让线程暂停。

多个线程处于可运行状态

关于线程调度的问题,多线程并发时,我们可以控制线程的优先级(优先级越高,越有可能被执行到,也不是绝对的)

优先级:反映线程得重要或紧急程度

线程的优先级用1~10表示,1的优先级最高,默认值是5

更改优先级:

setPriority(int grade)

myThread.setPriprity(3);

线程调度的方法:

join():将指定的线程加入到当前线程

sleep():将当前线程阻塞指定的毫秒数

现在我们遇到一个问题:

当两个或多个线程需要访问同一资源时,需要确保该资源某一时刻只能被一个线程使用,该如何实现

就引出了下面的知识点

1.同步方法(synchronized)

2.同步代码块(synchronized)

线程死锁也是多线程长遇到的问题,也很难避免

原文地址:https://www.cnblogs.com/hmy-1365/p/5528763.html