多线程编程

多线程:从软件或硬件实现多个线程并发执行的技术。一个程序中,独立运行的程序片段称为线程。

两个例子理解多线程:
1、工厂和工厂线:工厂理解为进程,工厂线理解为线程,多个工厂线同时进行,从而提高效率;
2、百度网盘下载多个内容:百度网盘为进程,多个下载线路为线程。从而提高整体下载效率。

多线程两种写法:(手写)

public class Thread1 extends Thread {
	public void run() {
		// 内容1
	}
}

Thread1 t1 = new Thread1();
public class Runnable1 implements Runnable {
	public void run() {
		// 内容2
	}
}

Thread1 t1 = new Thread1(new Runnable1());

线程安全

什么时候会出现线程安全问题?(线程之间相互独立)
例子:售票员A、B售票;共1、2、3、4、5、6、7、8、9、10十张票;
售票员A在售第3张票,售票员B也在售第3张票;从而出现线程安全问题。

如何解决线程安全问题?
原理:同步机制(锁)让某些共享数据代码通过加锁来保证在同一个线程下执行,不被其他线程参与执行过程;

两种加锁方式:

1、同步代码块
synchronized(this)

2、同步方法 (修饰符前面加关键字synchronized)
public synchronized void saleOne(){}

public class SaleWindow1 implements Runnable{

    private int id = 10; // 表示10张火车票,这是共享资源

    // 卖10张火车票
    public void run(){
        for (int i = 0; i < 10; i++) {

            synchronized (this){
                if(id > 0){
                    System.out.println(Thread.currentThread().getName() + "卖了编号为"+id+"的火车票");
                    id--;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }


        }
    }
}
public class SaleWindow2 implements Runnable{

    private int id = 10; // 表示10张火车票,这是共享资源

    public synchronized void saleOne(){
        if(id > 0){
            System.out.println(Thread.currentThread().getName() + "卖了编号为"+id+"的火车票");
            id--;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 卖10张火车票
    public void run(){
        for (int i = 0; i < 10; i++) {

            saleOne();
        }
    }
}

线程通信

比如我想1-10号火车票按照一定顺序卖票;而线程之间是相互独立的,那么通过什么来保证线程间通信?

等待唤醒机制
wait()方法和notify()方法

场景:筐子,最大放10个苹果(锁)、农夫(线程A)、小孩(线程B)
农夫放苹果,小孩从筐子里拿苹果;

筐子满10个苹果让农夫休息,wait(),某则小孩吃水果,唤醒notify()农夫放苹果;筐子里面苹果吃完让小孩休息;

public class Kuang {

    // 这个集合就是水果筐,假设最多存10个水果
    public static ArrayList<String> kuang = new ArrayList<String>();
}
public class Farmer extends Thread{
    @Override
    public void run() {
        while (true){
            //1、筐放满了就让农夫去休息
            synchronized (Kuang.kuang){
                if(Kuang.kuang.size()==10){
                    try {
                        Kuang.kuang.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 否则往筐里面放水果
                Kuang.kuang.add("apple");
                System.out.println("农夫放了一个水果,目前筐里面有"+Kuang.kuang.size()+"个水果");
                // 唤醒小孩继续吃
                Kuang.kuang.notify();
            }

            // 模拟控制速度
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
public class Child extends Thread{
    public void run(){
        while (true){
            synchronized (Kuang.kuang){
                // 筐里面没水果了就让小孩休息
                if(Kuang.kuang.size()==0){
                    try {
                        Kuang.kuang.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 有水果就继续吃
                Kuang.kuang.remove("apple");
                System.out.println("小孩吃了一个水果,目前筐里面有"+Kuang.kuang.size()+"个水果");
                // 唤醒农夫继续放水果
                Kuang.kuang.notify();

            }
            // 控制速度
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class TestFarmerChild {
    public static void main(String[] args) {
        new Farmer().start();
        new Child().start();
    }
}

实践

考评批量导出学生试卷采用多线程方式拼接试卷;

Thread thread = new Thread(new Runnable() {
	
	@Override
	public void run() {
			// 考生拼接试卷方法
	}
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值