Java 3 多线程

Java3 多线程


资料来源:《Java程序设计基础(第六版)》

Java支持多线程,使各代码段并发执行。

Q:并发和并行的区别
A:并行是指同一时刻有多个代码在处理器上执行,需硬件支持;并发执行是在单处理器上,同一时刻只能执行一个代码,但同一时段内代码段交替执行,实现“微观串行,宏观并行”。

基本概念:
程序(program):静态的代码
进程(process):一个运行中的程序。进程是操作系统资源分配和处理器调度的基本单元。
线程(thread):包含在进程内,同类的多个线程共享内存空间和系统资源

线程的5种状态

  • newborn:已经分配资源,未调度
  • runnable:可运行,进入线程队列等待CPU资源
  • running:线程对象拥有CPU控制权后调用run()方法
    正在运行的线程将在以下情况退出:
    1.线程执行完毕
    2.有优先级更高的线程处于runnable状态
    3.线程主动睡眠
    4.线程等待某一资源
  • blocked:因某种原因不能执行线程
    1.调用sleep() / yield()方法
    2.为等待条件变量,调用wait()方法
    3.与另一线程join()
  • dead:正常执行完后/进程停止运行时,线程变为dead状态

线程的调度

  1. 分时模型:CPU资源按时间片分配,时间片使用完毕必须让出
  2. 抢占模型:高优先级先执行

创建线程

  • Thread的子类
  • Runnable接口(解决多重继承的问题 ,有利于数据共享),注意实现了Runnable接口的类并不具有线程的支持,还必须使用Thread(Runnable target)创建线程对象
package src;

class MyThread implements Runnable{
    public void run() {
        for (int i = 0; i < 3; i++) {
            try {
                Thread.sleep((int)(1000 * Math.random()));
            } catch (InterruptedException e) {

            }
            System.out.println(Thread.currentThread().getName() + " is running");
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyThread());
        Thread t2 = new Thread(new MyThread());
        t1.start();
        t2.start();
        System.out.println("Main Thread");
    }
}
Output:
Main Thread
Thread-0 is running
Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-1 is running
Thread-1 is running

join()方法
调用此方法的线程立即执行,正在执行的线程转为Runnable状态,且需要等到之前的线程执行完。

// 修改之前的main方法
public static void main(String[] args) {
    Thread t1 = new Thread(new MyThread());
    Thread t2 = new Thread(new MyThread());
    t1.start();
    try {
        t1.join();
    } catch (InterruptedException e) {
        System.out.println(t1.getName() + "interrupted");
    }
    t2.start();
    System.out.println("Main Thread");
}
Output:
Thread-0 is running
Thread-0 is running
Thread-0 is running
Main Thread
Thread-1 is running
Thread-1 is running
Thread-1 is running

线程间通信
wait():线程A执行了对象x的wait()方法,该线程暂停,进入x的等待队列,并释放x的互斥锁
notify():唤醒等待该对象互斥锁的第一个线程
notifyAll():唤醒等待该对象互斥锁的所有线程

一个线程基于对象x调用以上方法,该线程一定已经获得对象x的互斥锁,所以以上方法只能在sychronized代码块中调用

wait()和sleep()不同的地方是它暂时让出资源的控制权

例子:模拟一个存售票系统,必须满足售出一张后才能存入下一张

package src;

public class TicketSell {
    public static void main(String[] args) {
        Tickets t = new Tickets(10);
        new Producer(t).start();
        new Consumer(t).start();
    }
}

class Tickets {
    int size;
    int num = 0;
    boolean available = false;
    public Tickets(int size) {
        this.size = size;
    }
    public synchronized void put() {
        if (available) {// need to sell first
            try {
                wait();
            } catch (Exception e) {
            }
        }
        System.out.println("Store ticket " + num);
        available = true;
        notify();
    }
    public synchronized void sell() {
        if (!available) {// need to put first
            try {
                wait();
            } catch (Exception e) {
            }
        }
        System.out.println("Sell ticket " + num++);
        available = false;
        notify();
    }
}

class Producer extends Thread {
    Tickets t;
    public Producer(Tickets t) {
        this.t = t;
    }
    public void run() {
        while (t.num < t.size) {
            t.put();
        }
    }
}
class Consumer extends Thread {
    Tickets t;
    public Consumer(Tickets t) {
        this.t = t;
    }
    public void run() {
        while (t.num <= t.size) {
            t.sell();
        }
    }
}
Output:
Store ticket 0
Sell ticket 0
Store ticket 1
Sell ticket 1
Store ticket 2
Sell ticket 2
Store ticket 3
Sell ticket 3
Store ticket 4
Sell ticket 4
Store ticket 5
Sell ticket 5
Store ticket 6
Sell ticket 6
Store ticket 7
Sell ticket 7
Store ticket 8
Sell ticket 8
Store ticket 9
Sell ticket 9
Store ticket 10
Sell ticket 10

Process finished with exit code 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值