Java线程Thread(二)

来源:互联网 发布:淘宝退款蚂蚁借呗骗局 编辑:程序博客网 时间:2024/05/16 18:27

1,  线程间的数据共享会带来一些不确定性,为了保证线程间的数据共享的可预测,我们通常采用”同步”与“互斥” 。

2,  线程间数据共享一般采用两种方式:

a)        将数据封装在一个外部对象中,并把这个对象实例分别传入不同的线程

b)        线程Runnable的成员变量,在同一个在Runnable实例的多个线程(Thread)中共享成员变量

3,  线程间互斥,Java内置了synchronize关键字,通过该关键字和对象锁实现线程间的互斥。

public classRunnable1 implementsRunnable {

   public int x;

   public static void main(String[] args) {

      Runnable1r1 = new Runnable1();

      Threadt1 = new Thread(r1);

      Threadt2 = new Thread(r1);

      t1.start();

      t2.start();

   }

   @Override

   public void run() {

      int hold;

      for (;;) {

         synchronized (this) {

            hold = x + 1;

            try {

                Thread.sleep(1000);

            }catch(Exceptione) {

            }

            x = hold;

            System.out.println(x);

         }

      }

   }

}

如上通过成员变量x实现了线程t1和t2之间的数据共享,通过synchronized (this) 语句块实现t1和t2两个线程间的互斥,当线程t1获得了r1锁时,线程t2需要等待t1的synchronized语句块结束并释放r1锁,t2才能获取r1锁并进入synchronized语句块。

4,  在Java中每一个对象都有一个对象锁,而且有且只有一个对象锁。当一个线程进入到synchronize块就获取了该对象的锁,当推出synchronize块时返回对象锁。

5,  Synchronize不是保护数据不被访问,而是保证数据在同一时刻只有一个线程访问。Synchronize既可以放在方法前,也可加在特定代码块前。

6,  Synchronize如果使用不当可能会导致死锁:

语句一

synchronized(a){

synchronized(b){

      ……

}

}

语句二

synchronized(b){

synchronized(a){

      ……

}

}

如上,如果语句一和语句二同时进入,语句一持有a的锁等待b的锁,同时语句二持有b的锁等待a的锁,两个语句块互相持有彼此需要的锁,相互等待,两个线程都无法继续运行,就进入死锁状态。所以当线程中使用嵌套锁时,尽量保证,所有嵌套锁的顺序相同。


原文链接

以上笔记,如有错误请指正

1 0
原创粉丝点击