程序
- 一段静态的代码,没有被执行,只是写好了完整的代码;
进程
- 程序的执行过程;
线程
- 进程的小单元,可以同时进行线程;
- 单线程:程序运行的过程中,只有一个进程;
多线程
- 多进程:程序运行的过程中,有多个线程并发进行;
- 多进程的类一般都继承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 。