Java多线程(二)

本文详细介绍了Java多线程中的同步机制,包括同步代码块、同步方法、线程安全的单例模式、锁的概念及类型,以及死锁问题和Lock锁的使用,旨在解决多线程安全问题。
摘要由CSDN通过智能技术生成

Java多线程(二)

四、线程的同步

4.1 线程同步的引入:
  • 多线程出现了安全问题
  • 问题的原因: 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。例如:买票问题、银行卡消费问题等等。
  • 解决办法: 对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行

​ 所以,Java 对于多线程的安全问题提供了专业的解决方式:同步机制

4.2 线程同步的方式之一:同步代码块
  1. 语法格式:
synchronized (对象/同步监视器){
   	//得到对象的锁,才能操作同步代码
	// 需要被同步的代码
}

说明:

​ (1)操作共享数据的代码,即为需要被同步的代码。 --> 不能包含代码多了,也不能包含代码少了。

​ (2)共享数据:多个线程共同操作的变量。

​ (3)同步监视器,俗称:锁。任何一个类的对象,都可以充当锁

​ (4)要求:多个线程必须要共用同一把锁

  1. 使用同步代码块解决在实现 Runnable 接口的方式创建多线程的线程安全问题
//	例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的方式
class Window1 implements Runnable{
   

    private int ticket = 100;
//    Object obj = new Object();
    @Override
    public void run() {
   
//      Object obj = new Object();
        while(true){
   
            // 同步代码块---begin
            synchronized (this){
   	// 此时的this:唯一的 Window1 的对象w   //方式二:synchronized (object) {
   

                if (ticket > 0) {
   

                    try {
   
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
                    ticket--;
                } else {
   
                    break;
                }
            }
            // 同步代码块---end
        }
    }
}

public class WindowTest1 {
   
    public static void main(String[] args) {
   
        Window1 w = new Window1();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}
  1. 使用同步代码块解决继承 Thread 类的方式创建多线程的线程安全问题
class Window2 extends Thread{
   

    private static int ticket = 100;
//    private static Object obj = new Object();

    @Override
    public void run() {
   

        while(true){
   

            synchronized (Window2.class){
   //	Window2.class表示window2这一个类,只会加载一次
//       方式二:synchronized (obj){	               
//              synchronized (this){	错误的方式:this分别代表着t1,t2,t3三个对象

                if(ticket > 0){
   

                    try {
   
                        Thread.sleep(100);
                    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值