天天看点

多线程——生命周期/同步

多线程——生命周期/同步

方式一:同步代码块

  • synchronized(同步监视器){
  • 需要被同步的代码
  • }
  • 说明:1.操作共享数据的代码,即为需要被同步的代码。 -->不能包含代码多了,也不能包含代码少了。
  • 2.共享数据:多个线程共同操作的变量。比如:ticket就是共享数据。
  • 3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。
  • 要求:多个线程必须要共用同一把锁。
  • 补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。

    例子:

synchronized (this){//此时的this:唯一的Window1的对象   //方式二:synchronized (dog) {

                if (ticket > 0) {

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

                    System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);


                    ticket--;
                } else {
                    break;
                }
            }
           

说明:在继承Thread类创建多线程的方式中,慎用this充当同步监视器,考虑使用当前类充当同步监视器。

例子:

synchronized (Window2.class){//Class clazz = Window2.class,Window2.class只会加载一次,不能用this

                if(ticket > 0){

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

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

方式二:同步方法

  • 如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的。
  • 5.同步的方式,解决了线程的安全问题。—好处
  • 操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低。 —局限性

关于同步方法的总结:

    1. 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
    1. 非静态的同步方法,同步监视器是:this

      静态的同步方法,同步监视器是:当前类本身

      例子:

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--;
            }
}
           

使用同步方法处理继承Thread类的方式中的线程安全问题(将同步的方法设置维static)

例子:

private static synchronized void show(){//同步监视器:Window4.class
   
        if (ticket > 0) {

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }          System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
            ticket--;
        }
    }
           

如果锁住的代码有wait(),线程进入阻塞状态。锁会打开