读马士兵java高并发编程,引用他的代码,做个记录。
一、分析下面程序输出:
/** * 分析一下这个程序的输出 * @author mashibing */ package yxxy.c_005; public class T implements Runnable { private int count = 10; public synchronized void run() { count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } public static void main(String[] args) { T t = new T(); for(int i=0; i<5; i++) { new Thread(t, "THREAD" + i).start(); } } }
THREAD0 count = 9 THREAD4 count = 8 THREAD1 count = 7 THREAD3 count = 6 THREAD2 count = 5
分析:
启动了5个线程,thread0先拿到这把锁,开始执行,thread1-4都在等待准备抢这把锁;thread0执行完之后,释放锁;thread4率先抢到了这把锁,开始执行;执行完之后thread1又抢到了这把锁,开始执行....;
所以看到每次线程访问一次,count-1;而且thread执行的先后顺序每次执行的结果不同,因为你不知道哪个线程先执行了;
二、对比上一个程序,分析这个程序的输出:
/** * 对比上面一个小程序,分析一下这个程序的输出 * @author mashibing */ package yxxy.c_006; public class T implements Runnable { private int count = 10; public synchronized void run() { count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } public static void main(String[] args) { for(int i=0; i<5; i++) { T t = new T(); new Thread(t, "THREAD" + i).start(); } } }
THREAD0 count = 9 THREAD4 count = 9 THREAD3 count = 9 THREAD1 count = 9 THREAD2 count = 9
分析:
启动了5个线程,因为每次都是new了一个t,每个线程都能锁住t,一共有5个t,5个count;所以这里5个线程执行完,count都是9;
但是因为不知道哪个线程先被cpu执行,所以thread名字的顺序是随机的;
三、同步和非同步方法是否可以同时调用?
/** * 同步和非同步方法是否可以同时调用? * @author mashibing */ package yxxy.c_007; public class T { public synchronized void m1() { System.out.println(Thread.currentThread().getName() + " m1 start..."); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " m1 end"); } public void m2() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " m2 "); } public static void main(String[] args) { T t = new T(); new Thread(()->t.m1(), "t1").start(); new Thread(()->t.m2(), "t2").start(); } }
t1 m1 start...
t2 m2
t1 m1 end
分析:
t1线程执行m1方法,开始睡10s,在这过程之中,t2线程执行m2方法,5s之后打印了m2;由此可见在m1执行的过程之中,m2是可以运行的。
同步方法的执行过程中,非同步方法是可以执行的。只有synchronized这样的方法在运行时候才需要申请那把锁,而别的方法是不需要申请那把锁的。
new Thread(()->t.m1())这个写法是java8里面的Lambda表达式,一种简写,还可以写成这样:
public static void main(String[] args) { T t = new T(); new Thread(t::m1, "t1").start(); new Thread(t::m2, "t2").start();*/ }
就是之前最原始的写法:
public static void main(String[] args) { T t = new T(); new Thread(new Runnable(){ @Override public void run() { t.m1(); } }, "t1").start(); new Thread(new Runnable(){ @Override public void run() { t.m2(); } }, "t2").start(); }
四、