java 同步和异步

  我想的有点杂,先写在说。

 

1,关于线程安全,如果一个方法里面全部是局部变量,那么是没有必要同步的,也就是说它是线程安全的。也就是不必加synchronized,servelet里面的的HttpServlet就是这样,  PrintWriter out = response.getWriter();这句话中这个out流本来可以作为HttpServlet的类变量的,但是如果是那样就需要同步了,影响效率呀。

 

2,关于锁,

class Test{
    public synchronized void f1(){
    //do something here
    }
    public void f2(){
    synchronized(this){
    //do something here
    }
    }
    }

 

 

上面的f1()和f2()效果一致, synchronized取得的锁都是Test某个实列(this)的锁.
    比如: Test t = new Test();
    线程A调用t.f2()时, 线程B无法进入t.f1(),直到t.f2()结束.
    作用: 多线程中访问Test的同一个实例的同步方法时会进行同步.
也就是说在f1()前面加上synchronized ,那线程在调用这个方法的时候取得了这个对象的锁,也就是t的锁,

 

其他的线程想访问t的其他同步方法,比如f2()就不行,其实这样是不好的,很多时候我们用另外实例变量来锁。

 

class Test{

  private static final Object obj=new Object();
    public synchronized void f1(){
    //do something here
    }
    public void f2(){
    synchronized(obj){
    //do something here
    }
    }
    }

 此时,如果一个线程访问f2,它拿到的是obj对象的锁,别的线程依然可以访问f1().

 

3,原子性,先看代码:

 

package com.test;



public class Test extends Thread {

  private int a = 0;

  private int b = 0;

  public static void main(String[] args) {

    Test test = new Test();

    for (int i = 0; i < 10; i++) {

      Thread thread = new Thread(test, "thread-" + i);

      thread.start();

    }

  }

  public synchronized void doWrite() {

    a++;

    try {

      sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

    b++;

    try {

       sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

  }

  public synchronized void print() {

    System.out.println("" + Thread.currentThread().getName() + ":a:" + a);

    System.out.println("" + Thread.currentThread().getName() + ":b:" + b);

  }

  public void run() {
     f();
   
  }

  public   synchronized  void f() {
    for (int i = 0; i < 5; i++) {

      doWrite();

      print();

    }
  }

}

 

 

输出结果:

thread-0:a:1
thread-0:b:1
thread-0:a:2
thread-0:b:2
thread-0:a:3
thread-0:b:3
thread-0:a:4
thread-0:b:4
thread-0:a:5
thread-0:b:5
thread-1:a:6
thread-1:b:6
thread-1:a:7
thread-1:b:7
thread-1:a:8
thread-1:b:8
thread-1:a:9
thread-1:b:9
thread-1:a:10
thread-1:b:10
thread-2:a:11
thread-2:b:11
thread-2:a:12
thread-2:b:12
thread-2:a:13
thread-2:b:13
thread-2:a:14
thread-2:b:14
thread-2:a:15
thread-2:b:15
thread-3:a:16
thread-3:b:16
thread-3:a:17
thread-3:b:17
thread-3:a:18
thread-3:b:18
thread-3:a:19
thread-3:b:19
thread-3:a:20
thread-3:b:20
thread-4:a:21
thread-4:b:21
thread-4:a:22
thread-4:b:22
thread-4:a:23
thread-4:b:23
thread-4:a:24
thread-4:b:24
thread-4:a:25
thread-4:b:25
thread-5:a:26
thread-5:b:26
thread-5:a:27
thread-5:b:27
thread-5:a:28
thread-5:b:28
thread-5:a:29
thread-5:b:29
thread-5:a:30
thread-5:b:30
thread-6:a:31
thread-6:b:31
thread-6:a:32
thread-6:b:32
thread-6:a:33
thread-6:b:33
thread-6:a:34
thread-6:b:34
thread-6:a:35
thread-6:b:35
thread-7:a:36
thread-7:b:36
thread-7:a:37
thread-7:b:37
thread-7:a:38
thread-7:b:38
thread-7:a:39
thread-7:b:39
thread-7:a:40
thread-7:b:40
thread-8:a:41
thread-8:b:41
thread-8:a:42
thread-8:b:42
thread-8:a:43
thread-8:b:43
thread-8:a:44
thread-8:b:44
thread-8:a:45
thread-8:b:45
thread-9:a:46
thread-9:b:46
thread-9:a:47
thread-9:b:47
thread-9:a:48
thread-9:b:48
thread-9:a:49
thread-9:b:49
thread-9:a:50
thread-9:b:50

 我们可以看到是很标准的输出。

 

我们在run方法里面改点东西:

 

package com.test;



public class Test extends Thread {

  private int a = 0;

  private int b = 0;

  public static void main(String[] args) {

    Test test = new Test();

    for (int i = 0; i < 10; i++) {

      Thread thread = new Thread(test, "thread-" + i);

      thread.start();

    }

  }

  public synchronized void doWrite() {

    a++;

    try {

      sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

    b++;

    try {

       sleep((int)(Math.random()*100));

    }

    catch (Exception e) {

    }

  }

  public synchronized void print() {

    System.out.println("" + Thread.currentThread().getName() + ":a:" + a);

    System.out.println("" + Thread.currentThread().getName() + ":b:" + b);

  }

  public void run() {
    for (int i = 0; i < 5; i++) {

      doWrite();

      print();

    }
   
  }

  

}

 

输出的结果就不确定了:

 

thread-0:a:10
thread-0:b:10
thread-1:a:10
thread-1:b:10
thread-2:a:10
thread-2:b:10
thread-3:a:10
thread-3:b:10
thread-4:a:10
thread-4:b:10
thread-5:a:10
thread-5:b:10
thread-6:a:10
thread-6:b:10
thread-7:a:10
thread-7:b:10
thread-8:a:10
thread-8:b:10
thread-9:a:10
thread-9:b:10
thread-0:a:20
thread-0:b:20
thread-1:a:20
thread-1:b:20
thread-2:a:20
thread-2:b:20
thread-3:a:20
thread-3:b:20
thread-4:a:20
thread-4:b:20
thread-5:a:20
thread-5:b:20
thread-6:a:20
thread-6:b:20
thread-7:a:20
thread-7:b:20
thread-8:a:20
thread-8:b:20
thread-9:a:20
thread-9:b:20
thread-0:a:30
thread-0:b:30
thread-1:a:30
thread-1:b:30
thread-2:a:30
thread-2:b:30
thread-3:a:30
thread-3:b:30
thread-4:a:30
thread-4:b:30
thread-5:a:30
thread-5:b:30
thread-6:a:30
thread-6:b:30
thread-7:a:30
thread-7:b:30
thread-8:a:30
thread-8:b:30
thread-9:a:30
thread-9:b:30
thread-0:a:40
thread-0:b:40
thread-1:a:40
thread-1:b:40
thread-2:a:40
thread-2:b:40
thread-3:a:40
thread-3:b:40
thread-4:a:40
thread-4:b:40
thread-5:a:40
thread-5:b:40
thread-6:a:40
thread-6:b:40
thread-7:a:40
thread-7:b:40
thread-8:a:40
thread-8:b:40
thread-9:a:40
thread-9:b:40
thread-0:a:50
thread-0:b:50
thread-1:a:50
thread-1:b:50
thread-2:a:50
thread-2:b:50
thread-3:a:50
thread-3:b:50
thread-4:a:50
thread-4:b:50
thread-5:a:50
thread-5:b:50
thread-6:a:50
thread-6:b:50
thread-7:a:50
thread-7:b:50
thread-8:a:50
thread-8:b:50
thread-9:a:50
thread-9:b:50

 

 

我们的目的就是要 完数据后在输出,所以应该确保这个过程的原子性。直接写在run方法里面就没能确保原子性。

先写到这,以后在加吧。

你可能感兴趣的:(java,多线程,thread,F#)