4多线程-代码安全,同步代码块

多次启动一个线程是非法的

静态是线程安全的。 但不是绝对的线程安全。 
 
使用Runnable 接口的形式

class runDate(){
  public void     run(){
  }
}
class ddd(){
    psvm(){
       runData r=  new runData();
      
      Thread t=new Thread(r);
      Thread t1=new Thread(r);
      Thread t2=new Thread(r);
     t.start();
    t1.start();
    t2.start();
    }
}


这种形式虽然创建了多了线程。 但是因为传入的r是同一个对象。 随意这样四个线程的t是线程共享的。 可以实现4个线程卖100个票的例子。 

而继承Thread类形式。因为每创建一个线程,就要创建一个本身的示例。 所以每个线程运行的线程任务实例 都是单独的。所以会出现卖了400张票的问题

线程安全问题的现象

线程安全问题产生的原因:

  1. 多个线程在操作共享的数据包。
  2. 操作共享数据的线程代码有多条。

当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。
就会导致线程安全问题的产生。

解决思路:
就是将多条操作共享数据的线程代码封装起来。当有线程在执行这些代码的时候,
其他线程是不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。

同步代码块

在java中用同步代码块就可以解决这个问题。

同步代码块的格式
synchronized(对象){
    需要被同步的代码;
}

同步的好处: 解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁。

同步的前提

同步的前提:必须有多个线程并使用同一个锁

同步函数

public synchronized void add(int num){

}

同步函数的锁是this 即当前对象。

同步函数和同步代码块的区别:
        1.同步函数的锁是固定的this。
        2.同步代码块的锁是任意的对象。也可以是this.
建议使用同步代码块。

静态同步代码块的锁

静态的同步函数时没有this的。
静态的同步函数使用的锁是 该函数所属字节码文件对象。 可以用 getClass方法获取。
也可以用当前类名.class 表示

单例模式涉及到多线程问题

  实际代码中,尽量使用饿汉式。
  面试时可能会问懒汉式
同步判断懒汉式单例

死锁示例



class Test implements Runnable {
    private boolean flag = true;

    Test(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if (flag) {
            synchronized (MyLock.LOCK_A) {
                System.out.println("if      LOCK_A,,,");
                synchronized (MyLock.LOCK_B) {
                    System.out.println("if      LOCK_B,,,");
                }
            }
        } else {
            synchronized (MyLock.LOCK_B) {
                System.out.println("else      LOCK_B,,,");
                synchronized (MyLock.LOCK_A) {
                    System.out.println("else      LOCK_A,,,");
                }
            }
        }
    }
}

class MyLock {
    static final Object LOCK_A = new Object();
    static final Object LOCK_B = new Object();
}

class DeadLockTest {
    public static void main(String[] args) {
        Test a = new Test(true);
        Test b = new Test(false);
        Thread t1 = new Thread(a);
        Thread t2 = new Thread(b);
        t1.start();
        t2.start();
    }


郁闷解惑

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容