2020-07-27 线程的同步(安全问题)方法一:同步代码块

2020-07-27  本文已影响0人  DM小强

1.同步代码块

实现方法一:实现Runnable接口

package com.dm.java;

**
 *
 * 1.问题:卖票过程中出现重票或者错票的问题----->出现了线程的安全问题
 * 2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其它线程参与进来,也操作车票
 * 3.如何解决:当一个线程在操作ticket的时候,其它线程不能参与进来。直到当前线程操作完ticket时,其它线程才能开始操作
 *  这种情况即时当前线程出现了阻塞,也不能被改变
 *  4.在JAVA中,通过同步机制,来解决线程的安全问题
 *
 *  方式一:同步代码块
 *
 *  synchronized(同步监视器){
 *      //需要被同步的代码
 *  }
 *  说明:1.操作共享数据的代码,即为需要被同步的代码。---->不能包含多了,也不能包含代码少了。
 *       2. 共享数据:多个线程共同操作的变量。比如当前代码的ticket
 *       3.同步监视器:俗称:锁。任何一个类的对象,都可以充当锁。
 *          要求:多个线程必须要共用通一把锁。
 *       补充:在实现Runnable接口创建多线程的方式中,可以考虑用this充当同步监视器。
 *
 *  方式二:同步方法(见下一章)
 *
 *
 * @author JessieWu
 * @create 2020-07-27  15:28
 */

class Window implements Runnable{
    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj) {//synchronized (this)这样也是可以的
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
                    ticket--;
                } else {
                    break;
                }
            }
        }
    }
}

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

        t1.setName("窗口一");
        t2.setName("窗口二");
        t3.setName("窗口三");

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

    }
}

实现方二:实现Thread类继承

package com.dm.java;

/** 继承的方式
 *
 * 在继承Thread类创建多线程的方式中,慎用this充当同步监视器。考虑使用当前类充当监视器
 * @author JessieWu
 * @create 2020-07-27  16:24
 */


class MyThread extends Thread{
    static Object obj = new Object();
    private static int ticket = 100;
    @Override
    public void run() {
        while (true){
            synchronized (obj){ //synchronized (Windows.class)这样也是可以的
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ":卖票,票号为" + ticket);
                    ticket--;
                } else {
                    break;
                }
            }
        }
    }
}
public class WindowTest1 {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();
        t1.setName("窗口一");
        t2.setName("窗口二");
        t3.setName("窗口三");
        t1.start();
        t2.start();
        t3.start();
    }
}

上一篇下一篇

猜你喜欢

热点阅读