【问题一】
class Number{
public synchronized void a() {
System.out.println(1);
}
public synchronized void b() {
System.out.println(2);
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
}
输出:
分析:创建出的线程1和线程2,锁住的是同一对象n1, public synchronized void a() 等价于
public void a() {
synchronized(this) {}
}
而两线程的运行是并行的,也就是运行顺序是随机的,所以运行的结果如上图。
【问题二】
class Number{
public synchronized void a() {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println(1);
}
public synchronized void b() {
System.out.println(2);
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
}
输出:
分析: 原因同上一题是一样的,不一样之处在于线程1在运行时睡眠了1秒钟,但这并不影响输出顺序。首先电脑随机选出先运行的线程,一旦选定,线程进入owner将被上锁,上锁了之后,无论此线程睡眠多久,都要将它先执行完,再执行另一个线程。
【问题三】
class Number{
public synchronized void a() {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println(1);
}
public synchronized void b() {
System.out.println(2);
}
public void c() {
System.out.println(3);
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
new Thread(()->{ n1.c(); }).start();
}
}
输出:
分析:我们可以看到三个线程为同一对象,其中线程1,线程2上锁,线程3未上锁,所以线程3的完成取决于电脑的随机分配。而且线程1加上了睡眠时间,所以如果线程1和线程3同步运行,则线程3先运行完成。而线程2和线程3谁先运行完成取决于电脑的随机选择。线程1和线程2的先后顺序同上一道题。
【问题四】
class Number {
public synchronized void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(1);
}
public synchronized void b() {
System.out.println(2);
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(() -> {
n1.a();
}).start();
new Thread(() -> {
n2.b();
}).start();
}
}
输出:
分析:这里创建的是两个对象,两个线程分别拥有不同的对象,所以上不上锁其实是无所谓的,但是这里线程1有一个睡眠过程,所以线程2先输出。
【问题五】
class Number {
public synchronized static void a() { //锁住的是 Number.class
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println(1);
}
public synchronized void b() {//锁住的是n1
System.out.println(2);
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{ n1.a(); }).start();
new Thread(()->{ n1.b(); }).start();
}
}
输出:
分析:道理同上,线程1锁住的对象是Number.class,线程2锁住的对像是n1。public synchronized static void a()等效于:
public static void a() {
synchronized(Number.class) { }
}
【问题六】
class Number {
public synchronized static void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(1);
}
public synchronized static void b() {
System.out.println(2);
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(() -> {
n1.a();
}).start();
new Thread(() -> {
n1.b();
}).start();
}
}
输出:
分析:同【问题二】,线程1,2的对象都为Number.class。
【问题七】
class Number {
public synchronized static void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(1);
}
public synchronized void b() {
System.out.println(2);
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(() -> {
n1.a();
}).start();
new Thread(() -> {
n2.b();
}).start();
}
}
输出:
分析:线程1的对象为Number.class,线程2的对象为n2,两个线程同时运行,但是线程1睡眠了1秒钟,所以线程2先输出,再输出线程1的1。
【问题八】
class Number {
public synchronized static void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(1);
}
public synchronized static void b() {
System.out.println(2);
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(() -> {
n1.a();
}).start();
new Thread(() -> {
n2.b();
}).start();
}
}
输出:
分析:锁住的是同一对象Number.class,故先运行那个线程由电脑随机给出。
日常鸡汤:每一个优秀的人,都有一段沉默的时光
是那一段时光,不抱怨不诉苦
最后渡过了这段感动自己的日子。。。