美文网首页
线程同步

线程同步

作者: 冯宏志 | 来源:发表于2020-12-13 15:20 被阅读0次
线程的同步
  • 当一个线程a在操作共享数据的时候,其他线程不能参与进来,直到线程a操作完共享数据,其他线程才能操作共享数据
  • 方式一 synchronize
synchronize(同步监视器){
  //需要被同步的代码
}

说明:
1、操作共享数据的代码,即为需要被同步的代码 不能包多也不能包少
2、同步监视器,俗称:锁。任何一个类的对象都可以充当锁
要求多个线程必须拥有同一把锁
补充:
在实现Runnable接口创建多线程的方式中,我们还可以考虑使用this充当同步监视器
在继承Thread类创建多线程的方式中,慎用this充当同步监视器。可以考虑使用当前类充当同步监视器。

  • 方式二:同步方法
    如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的。

总结:
1、同步方法仍然涉及到同步监视器,只是不需要我们显式的声明
2、非静态的同步方法,同步监视器是this
3、静态的同步方法,同步监视器是当前类本身

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

        window1.setName("窗口1");
        window2.setName("窗口2");
        window3.setName("窗口3");

        window1.start();
        window2.start();
        window3.start();
    }
}

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

    @Override
    public void run() {
       while (true) {
           synchronized(obj){//这里也可以用Window1.class来代替
               if (ticket > 0) {
                   try {
                       Thread.sleep(100);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }

                   System.out.println(Thread.currentThread().getName() + "买票,票号为:" + ticket);
                   ticket--;
               } else
                   break;
           }
       }
    }
}
public class WindowTest2 {
    public static void main(String[] args) {
        Window2 window2 = new Window2();
        Thread t1 = new Thread(window2);
        Thread t2 = new Thread(window2);
        Thread t3 = new Thread(window2);

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

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

class Window2 implements Runnable{
    public static int ticket = 100;
    public Object obj = new Object();
    @Override
    public void run() {
        while (true) {
            synchronized(this){//此时的this就是唯一的Window2对象  //或者用obj
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + "买票,票号为:" + ticket);
                    ticket--;
                } else
                    break;
            }

        }

    }
}
public class WindowTest3 {
    public static void main(String[] args) {
        Window3 t1 = new Window3();
        Window3 t2 = new Window3();
        Window3 t3 = new Window3();

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

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

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

    @Override
    public void run() {
        while(true){
            show();
        }

    }

    private static synchronized void show(){//同步方法注意要加static//同步监视器默认为Window3.class
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "买票,票号为:" + ticket);
                    ticket--;
                }
    }

}

public class WindowTest4 {
    public static void main(String[] args) {
        Window4 window4 = new Window4();
        Thread t1 = new Thread(window4);
        Thread t2 = new Thread(window4);
        Thread t3 = new Thread(window4);

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

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

class Window4 implements Runnable{
    private static int ticket = 100;
    private static Object obj = new Object();

    @Override
    public void run() {
        while(true){
            show();
        }

    }

    private synchronized void show(){//同步方法//同步监视器默认为this
        if (ticket > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "买票,票号为:" + ticket);
            ticket--;
        }
    }
}

相关文章

网友评论

      本文标题:线程同步

      本文链接:https://www.haomeiwen.com/subject/aimaiktx.html