多线程问题个人笔记

线程安全问题

线程安全问题原因

​ 1.多线程

​ 2.多个线程共享数据

​ 3.多条语句操作共享数据

线程安全问题解决

​ 使用synchronized关键字实现同步机制

​ 1.使用同步代码块

​ 2.使用同步方法

锁对象:可以是任意对象

​ 多个线程必须使用同一把锁对象,通常使用什么对象作为锁对象

​ 非静态域中shiyongthis作为锁对象

​ 比如:非静态同步代码块,非静态同步方法使用this

​ 静态域中使用类的Class对象

​ 比如:静态代码块,静态方法中使用Class对象

单例模式-懒汉式线程安全问题
public class SingletonDemo {
    private static SingletonDemo instence = null;

    public static SingletonDemo getInstence() {
        if (instence == null) {
            synchronized (SingletonDemo.class) {
                if (instence == null) {
                    instence = new SingletonDemo();
                }
            }
        }
        return instence;
    }

    private SingletonDemo() {
    }
}
常见线程安全的类
StringBuffer stringbuffer;
Vector vector;
Hashtable hashtable;

使用同步机制时,同步方法或同步代码块包含的代码:要尽量少,但是要包括所有操作的共享资源的代码,否则解决不了线程安全问题。包含的代码过多会影响性能。

等待唤醒机制解决经典生产者和消费者问题

/**
 * @version 1.0
 * @author: chutao
 * 案例:有家餐馆的取餐口比较小,只能放10份快餐,厨师做完快餐放在取餐口的工作台上,
 * 服务员从这个工作台取出快餐给顾客。现在有1个厨师和1个服务员。
 * 等待唤醒机制解决经典生产者和消费者问题
 */
public class Demo {
    public static void main(String[] args) {
        //创建共享资源类
        WorkBench workBench = new WorkBench();
        //创建线程任务类
        Waiter waiter = new Waiter(workBench);
        Cooker cooker = new Cooker(workBench);
        //创建线程
        new Thread(waiter, "服务员").start();
        new Thread(cooker, "厨师").start();
    }
}

class Waiter implements Runnable {
    private WorkBench workBench;

    public Waiter(WorkBench workBench) {
        this.workBench = workBench;
    }

    @Override
    public void run() {
        while (true) {
            workBench.take();//从工作台取走
        }
    }
}

//线程任务类
class Cooker implements Runnable {
    private WorkBench workBench;

    public Cooker(WorkBench workBench) {
        this.workBench = workBench;
    }

    @Override
    public void run() {
        while (true) {
            workBench.put();//生产快餐,放到工作台
        }
    }
}

//共享资源类
class WorkBench {
    private int MAX_VALUE = 10;//最大餐数
    private int num;//工作台当前餐数

    //往工作台放快餐的同步方法
    public synchronized void put() {
        if (num >= MAX_VALUE) {
            try {
                this.wait();//等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "----生产了" + ++num);

        //唤醒等待的另一个线程:随机唤醒一个等待的线程
        this.notify();
    }

    //从工作台取快餐的同步方法
    public synchronized void take() {
        if (num <= 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "----消费了" + --num);

        //唤醒等待的另一个线程
        this.notify();
    }
}
/**
 * @version 1.0
 * @author: chutao
 * 例:有家餐馆的取餐口比较小,只能放10份快餐,厨师做完快餐放在取餐口的工作台上,
 * 服务员从这个工作台取出快餐给顾客。现在有多个厨师和多个服务员。
 */
public class Demo {
    public static void main(String[] args) {
        //创建共享资源类
        WorkBench workBench = new WorkBench();
        //创建线程任务类
        Waiter waiter = new Waiter(workBench);
        Cooker cooker = new Cooker(workBench);
        //创建线程
        new Thread(waiter, "服务员1").start();
        new Thread(waiter, "服务员2").start();
        new Thread(waiter, "服务员3").start();
        new Thread(cooker, "厨师1").start();
        new Thread(cooker, "厨师2").start();
        new Thread(cooker, "厨师3").start();
    }
}

class Waiter implements Runnable {
    private WorkBench workBench;

    public Waiter(WorkBench workBench) {
        this.workBench = workBench;
    }

    @Override
    public void run() {
        while (true) {
            workBench.take();//从工作台取走
        }
    }
}

//线程任务类
class Cooker implements Runnable {
    private WorkBench workBench;

    public Cooker(WorkBench workBench) {
        this.workBench = workBench;
    }

    @Override
    public void run() {
        while (true) {
            workBench.put();//生产快餐,放到工作台
        }
    }
}

//共享资源类
class WorkBench {
    private int MAX_VALUE = 10;//最大餐数
    private int num;//工作台当前餐数

    //往工作台放快餐的同步方法
    public synchronized void put() {
        while (num >= MAX_VALUE) {
            try {
                this.wait();//等待,wait方法会释放锁对象
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "----生产了" + ++num);

        //唤醒等待的全部线程
        this.notifyAll();
    }

    //从工作台取快餐的同步方法
    public synchronized void take() {
        while (num <= 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "----消费了" + --num);

        //唤醒等待的全部线程
        this.notifyAll();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值