线程 进程 程序

程序

  • 一段静态的代码,没有被执行,只是写好了完整的代码;

进程

  • 程序的执行过程;

线程

  • 进程的小单元,可以同时进行线程;
  • 单线程:程序运行的过程中,只有一个进程;

多线程

  • 多进程:程序运行的过程中,有多个线程并发进行;
  • 多进程的类一般都继承Thread类,或者实现了Runnable接口;
       继承Thread类:重写其run方法,但是在程序运行的时候,需要调用start方法;
       实现Runnable接口:重写其run方法,程序在多线程的时候,调用run方法;
  • 多线程的优点:
       如果一个子线程阻塞,那么程序可以将CPU调度另外一个子线程进行工作,不会是释放进程。
       线程可以共享数据;
       线程通讯更加高效;
       线程更轻量级,容易切换;
       线程更加容易管理;  
    示例一个火车票系统
    Ticket类:用于显示火车票的起始站和终点站以及车票价钱。
package system12306;

public class Ticket {
    private String start;
    private String end;
    private Float price;
    private static Ticket ticket = new Ticket();

    private Ticket() {//私有的构造,别人不能自己创建对象
    }

    public static Ticket getInstance() {
        return ticket;//提供一个得到对象的方法
    }

    public Ticket(String start, String end, Float price) {//起点 终点 和票价
        this.start = start;
        this.end = end;
        this.price = price;
    }

    public String getStart() {
        return start;
    }

    public void setStart(String start) {
        this.start = start;
    }

    public String getEnd() {
        return end;
    }

    public void setEnd(String end) {
        this.end = end;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getStart() + "---->" + getEnd() + "======" + getPrice());
        return sb.toString();
    }
}

Window类:多个窗口同时售票,相当于多线程。

package system12306;

public class Window extends Thread {
    private String windowName;

    public String getWindowName() {
        return windowName;
    }

    public Window(String windowName) {
        this.windowName = windowName;//构造方法 该窗口的名字
    }

    @Override
    public void run() {
        this.sellTicket();//调用出售票的方法
    }

    private void sellTicket() {
        while (true) {
            System12306 system12306 = System12306.getInstance();
            Ticket ticket = system12306.getTicket();
            if (ticket == null) {
                System.out.println("当前窗口已售完!");
                break;
            }
            System.out.println("从" + windowName + "窗口售出" + ticket);
        }
    }
}

System12306类:将车票的信息加入到Vector集合中,采用Vector集合的原因是:Vector集合安全。

package system12306;

import java.util.Vector;

public class System12306 {
    private static System12306 sys = new System12306();

    private System12306() {
    }

    public static System12306 getInstance() {
        return sys;
    }

    private Vector<Ticket> vector = new Vector<>();

    {
        for (int i = 0; i < 100; i++) {
            vector.add(new Ticket("北京" + i, "深圳" + i, ((i % 5 + 5) * 25F)));
        }
    }
    public Ticket getTicket(){//取票的方法
        try {
            return vector.remove(0);//每次都取第一张票
        }catch (Exception e){
            return null;
        }
    }
}

主方法类

package system12306;

public class TestMain {
    public static void main(String[] args) {
        Window w1 = new Window("北京西站");
        Window w2 = new Window("北京东站");
        Window w3 = new Window("北京南站");
        w1.start();//三个线程同时抢票
        w2.start();
        w3.start();
    }
}

生产消费者模型
Producer类:加载生产者的生产过程。

package producer;

public class Producer extends Thread implements Runnable{
    WareHouse wareHouse= WareHouse.getInstance();
    public Producer(WareHouse wareHouse){
        this.wareHouse = wareHouse;
    }
    @Override
    public void run() {

        while (true){
            wareHouse.add();
            System.out.println("生产者生产了一件产品");
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Consumer:加载消费者的消费过程。

package producer;

public class Consumer extends Thread {
    WareHouse wareHouse = WareHouse.getInstance();
    public Consumer(WareHouse wareHouse){
        this.wareHouse = wareHouse;
    }
    @Override
    public void run() {

        while (true){
            wareHouse.getList();
            System.out.println("消费者消费了一件产品");
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

WraeHouse类:将生产者生产的产品存进去,消费者消费的产品移除。

package producer;

import java.util.ArrayList;

public class WareHouse {
    private static WareHouse wareHouse = new WareHouse();
    private ArrayList<String> list = new ArrayList<>();
    private WareHouse(){}
    public synchronized void add(){
        if (list.size() < 20){
            list.add("a");
        }else {
            try {
                this.notifyAll();
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static WareHouse getInstance(){
        return wareHouse;
    }
    public synchronized void getList(){
        if (list.size() > 0){
            list.remove(0);
        }else {
            this.notifyAll();
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


}

主方法类:

package producer;

public class TestMain {
    public static void main(String[] args) {
        WareHouse wareHouse = WareHouse.getInstance();
        Producer producer = new Producer(wareHouse);
        producer.setPriority(10);
        producer.start();
        Consumer consumer1 = new Consumer(wareHouse);
        consumer1.start();
        Consumer consumer2 = new Consumer(wareHouse);
        consumer2.start();
    }
}

  • syschronized是一个特征修饰符,为了防止第一个消费者在判断仓库里面的容量是否够用时,如果判断够用,第一个消费者还没有拿走这个产品,而第二个消费者拿走了这个产品,就会造成:IllegalMonitorStateException(非法状态监视异常)。
  • wait() 和 sleep()区别
             wait                    sleep
    所属类     Object类                  Thread类
            不能自动唤醒,需要其他对象          可以自动唤醒
            调用notify或者notifyAll唤醒 
                           
            对象调用                  静态修饰,Thread类调用
            等待后会释放锁                会释放锁
  • setPriority(int newPriority)可以设置线程的优先级,newPriority的取值范围是1~10 。
上一篇:1564 把箱子放进仓库里 I


下一篇:dubbo入门实践