Java 第十章

一、程序、进程、线程

  • 程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一 段静态的代码。
  • 进程((process)正在内存中运行的应用程序,如运行中的QQ,运行中的音乐播 放器。进程是操作系统进行资源分配的最小单位。
  • 线程(thread)进程可进一步细化为线程,是一个进程内部的最小执行单元,是操 作系统进行任务调度的最小单元,隶属于进程。

注:

  • 一个进程可以包含多个线程。
  • 一个线程只能属于一个进程,线程不能脱离进程而独立运行。
  • 每一个进程至少包含一个线程(称为主线程)。
  • 在主线程中可以创建并启动其它的线程。
  • 一个进程内的所有线程共享该进程的内存资源 

二、线程的创建 

代码示例如下:

/*
  创建线程方式1:
    MyThread 继承 Thread(线程)
   重写Thread类中的run()方法,  在run()方法中来编写我们需要执行的任务代码
 */
public class MyThread extends Thread{

    //run方法是线程执行任务的方法
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println("MyThread:"+i);
        }
    }

}
import java.io.Serializable;

/*
  创建一个任务,实现Runnable接口
  重写Runnable接口中的run方法
 */
public class MyTask  implements Runnable{


    @Override
    public void run() {
        //在任务中,我想知道当前是哪个线程正在执行我
         Thread thread =   Thread.currentThread();//在任务中,通过currentThread()获得当前正在执行的线程
         System.out.println(thread.getName());

        /*for (int i = 0; i <10000 ; i++) {
            System.out.println("mytask:"+i);
        }*/
    }

}

三、Thread类中的方法 

Java 第十章_第1张图片

四、线程的优先级 

  • 事实上,计算机只有一个CPU,各个线程轮流获得CPU的使用权,才能 执行任务。
  • 优先级较高的线程有更多获得CPU的机会,反之亦然。
  • 优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级 都是5,但是也可以通过setPriority和getPriority方法来设置或返回优先级。
  • 调度策略:
    时间片
    抢占式:高优先级的线程抢占CPU
  • java的调度方法:
    同优先级线程组成先进先出队列,使用时间片策略
    对高优先级,使用优先调度的抢占式策略

代码示例如下:

public class MyTask  implements  Runnable{


    @Override
    public void run() {

        Thread thread = Thread.currentThread();//获得当前正在执行此任务的线程
        /*if(thread.getName().equals("线程1")){
            try {
                Thread.sleep(4000);//让线程休眠 1000毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }*/
        System.out.println(thread.getName()+":"+thread.getPriority());//获得线程优先级
    }

}

 五、线程状态

Java 第十章_第2张图片

六、多线程的概念 

多线程是指程序中包含多个执行单元,即在一个程序中可以同时运行多 个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行 执行的线程来完成各自的任务 。

何时需要多线程

  • 程序需要同时执行两个或多个任务。
  • 程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、 网络操作、搜索等。

多线程的优点 

  • 提高程序的响应。
  • 提高CPU的利用率。
  • 改善程序结构,将复杂任务分为多个线程,独立运行。

多线程的缺点 

线程也是程序,所以线程需要占用内存,线程越多占用内存也越多; 多线程需要协调和管理,所以需要跟踪管理线程,使得cpu开销变大; 线程之间同时对共享资源的访问会相互影响,如果不加以控制会导致数据 出错

七、线程同步 

多个线程同时读写同一份共享资源时,可能会引起冲突。所以引入线程“同步”机制, 即各线程间要有先来后到。

 同步就是排队+锁:

  • 几个线程之间要排队,一个个对共享资源进行操作,而不是同时进行操作。
  • 为了保证数据在方法中被访问时的正确性,在访问时加入锁机制。

同步锁:同步锁可以是任何对象,必须唯一,保证多个线程获得是同一个对象(用 来充当锁标记)。

同步执行过程

  1. 第一个线程访问,锁定同步对象,执行其中代码。
  2. 第二个线程访问,发现同步对象被锁定,无法访问。
  3. 第一个线程访问完毕,解锁同步对象。
  4. 第二个线程访问,发现同步对象没有锁,然后锁定并访问 。

代码示例如下:

public class PrintNumThread  extends  Thread{

      static int  num = 0;
      static String object=new String();

      /*
         wait();   让线程等待,自动释放锁,必须要其他的线程唤醒
         notify(); 唤醒等待中的线程(调用了wait方法的线程),如果有多个等待,唤醒优先级高的
         notifyAll() 唤醒所有等待的线程

         这三个方法都是Object类中定义的方法,
         这三个方法必须在同步代码块中使用,
         这三个方法必须通过为锁的对象调用
       */

    @Override
    public void run() {

         while (true){
             synchronized (object){
                 object.notify();//唤醒等待中的线程
                 if(num<=100){
                     num++;
                     System.out.println(Thread.currentThread().getName()+":"+num);
                 }else{
                     break;
                 }
                 try {
                     object.wait();//让线程等待.同时释放了锁,等待的线程不能自己醒来,必须让另一个线程唤醒.
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         }

    }
}

 

/*
    柜台角色  共享数据
 */
public class Counter {

       int  num = 1; //代表商品的数量  例如为0

       //负责生产商品的方法  锁对象是this   add() 和 sub() 用的是同一把锁
       public synchronized void  add(){
             if(num==0){
                 System.out.println("生产者生产了一件商品");
                 num = 1;//生产一件商品
                 this.notify();//唤醒消费者线程
             }else{
                 try {
                     this.wait();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
       }
       //负责消费商品的方法
       public synchronized void sub(){
                if(num>0){
                    System.out.println("消费者拿走了一件商品");
                    num=0;//消费者拿走了商品
                    this.notify();
                }else{
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
       }
}


/*
    生产者线程
 */
public class ProductorThread extends  Thread{

    Counter counter;

    public ProductorThread(Counter counter) {
        this.counter = counter;
    }

    @Override
    public void run() {
        while (true){
            counter.add();//生产者线程  一直生产
        }
    }
}


public class CustomerThread  extends  Thread{

    Counter counter;

    public CustomerThread(Counter counter) {
        this.counter = counter;
    }

    @Override
    public void run() {
          while (true){
              counter.sub();  //消费者线程一直消费
          }
    }
}

 

你可能感兴趣的:(java,开发语言)