java基础——线程同步块

实现Runnable的线程同步块

package synchronization.block;

/*
@author zsben
@create 2020-01-03 13:48

创建三个窗口卖票,使用Runnable接口方式
1.问题:卖票过程中出现了重票,错票-->出现了线程安全问题
2.解决方案:当一个线程在操作ticket时,其他线程不能参与进来(即使该线程被阻塞)
           直到该线程操作完ticket,其他线程才可以参与进来,
3.java中通过同步机制进行解决

    方式一:同步代码块
        synchronized(同步监视器){
            //需要被同步的代码
        }
    说明:1.操作共享数据的代码,即需要被同步的代码
          2.共享数据:多个线程共同操作的变量(ticket)
          3.同步监视器:锁,任何对象都可以充当锁
            要求:多个线程必须要共用一把锁,可以考虑使用this来充当同步监视器
*/

class WindowRun implements Runnable{

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

    @Override
    public void run() {
        synchronized(this){  //此时this代表唯一的WindowRun对象,可以替代new obj
            while (true) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + ticket);

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

                    ticket--;
                } else break;
            }
        }
    }
}

public class WindowRunnableTest {
    public static void main(String[] args) {
        WindowRun windowRun = new WindowRun();

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

        t1.start();
        t2.start();
        t3.start();
    }
}

继承Thread的同步块

package synchronization.block;

/*
创建三个窗口买票,总票数为100张
存在线程安全问题:使用同步代码块解决继承Thread类的方式线程安全问题
可以考虑使用当前类来充当同步监视器

@author zsben
@create 2020-01-03 12:41
*/

class Window extends Thread{
    private static int ticket = 100;
    private static Object obj = new Object();

    @Override
    public void run() {
        while (true) {
            synchronized (Window.class) {
                //拿当前类对象充当锁,Class clazz = Window2.class,Window2.class只会加载一次
                if (ticket > 0) {
                    try {
                        sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName() + ": " + ticket);
                    ticket--;
                } else {
                    break;
                }
            }
        }

    }
}

public class WindowThreadTest {
    public static void main(String[] args) {
        Window t1 = new Window();
        Window t2 = new Window();
        Window t3 = new Window();

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

        t1.start();
        t2.start();
        t3.start();
    }
}

原文地址:https://www.cnblogs.com/zsben991126/p/12148291.html

时间: 2024-10-11 10:40:45

java基础——线程同步块的相关文章

Java多线程基础(四)Java传统线程同步通信技术

Java多线程基础(四)Java传统线程同步通信技术 编写代码实现以下功能 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次. 分析 1)子线程循环10次与主线程循环100次必须是互斥的执行,不能出现交叉,下面代码中通过synchronized关键字实现此要求: 2)子线程与主线程必须交替出现,可以通过线程同步通信技术实现,下面代码中通过bShouldSub变量实现此要求: 其他需要注意的地方 1)其中business变量必须声

Java 并发 线程同步

Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大多数实际的多线程应用中,两个或两个以上的线程需要共享对同一数据的存取,这将产生同步问题(可见性和同步性的丢失) 比如两个线程同时执行指令account[to] += amount,这不是原子操作,可能被处理如下: a)将account[to]加载到寄存器 b)增加amount c)将结果写回acco

Java基础——线程总结

Java基础--线程总结 一.线程是什么? 线程:一个程序里不同的执行路径. 二.如何创建线程? 两种方法创建线程: 第一种 (1)定义具体功能类实现Runnable接口,可以多次调用而实现数据共享 (2)Thread myThread = new Thread(-)          //参数为Runnable接口类型 (3)Runnable中只有一个方法 public void run(){--} //用以定义线程运行体 第二种 (1)定义一个Thread的子类并重写run()方法 clas

Java中线程同步的理解 - 其实应该叫做Java线程排队

Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等. 当多个线程同时读写同一份共享资源的时候,可能会引起冲突.这时候,我们需要引入线程"同步"机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团. 同步这个词是从英文synchronize(使同时发生)翻译过来的.我也不明白为什么

JAVA中线程同步的方法(7种)汇总

一.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类. 二.同步代码块 即有synchronized关键字修饰的语句块. 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步 代码如: synchronized(object){ } 注:同步是一种高开销

Java多线程 线程同步

如果你正在写一个变量,它可能接下来将被另一个线程读取,或者正在读取一个上一次已经被另一个线程写过的变量,那么你需要使用同步,并且,读写线程都必须用相同的监视器锁同步.--Brain同步规则 synchronized 所有对象都自动含有单一的锁,当在调用一个对象的任意synchronized方法时,此对象将被加锁. 对于某个特定对象来说,所有的synchronized方法共享同一个锁.所以某个线程在访问对象的一个synchronized方法时,其他线程访问该对象的任何synchronized方法都

Java多线程——线程同步

在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的控制吧. 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问.   一.多线程引起的数据访问安全问题 下面看一个经典的问题,银行取钱的问题: 1).你有一张银行卡,里面有50

java的线程同步机制synchronized关键字的理解

线程同步:               由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问. 需要明确的几个问题: 1)synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.如果 再细的分类,synchronized可作用于instance变量.object reference(对象引用).static函数和clas

JAVA多线程线程同步问题

线程同步 在多线程的编程环境下,可能看着没有问题的代码在运行几千上万或者更多次后,出现了一些看着很奇怪的问题,出现这样的问题的原因就是可能会有两个或者更多个线程进入了同一块业务处理代码中导致了判断失效.为了解决这个问题,JAVA引入了同步监视器来解决这个问题.同步监视器的通用方法就是同步代码块,也就是给一块代码加了同步锁. package cn.test.hf; import java.math.BigDecimal; /** * 模拟取钱操作 */public class RunnableTe