结论:串行
并发与串行其实是不同的概念,在单核CPU里面,所有指令都是串行的,并发指的在某一个时间段内,多个线程执行。与串行相对应的是并行,之后用串行和并行来区别。
public class SynchronizedObjectMethod3 implements Runnable {
static SynchronizedObjectMethod3 instance = new SynchronizedObjectMethod3();
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
// t1.join();
// t2.join();
while(t1.isAlive() || t2.isAlive()) {}
System.out.println("finished");
}
@Override
public void run() {
method();
}
public synchronized void method() {
System.out.println("I'm object method lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm object method lock " + Thread.currentThread().getName() + " is over");
}
}
尽管同步代码块对象锁是this,但这个this在起作用是两个不同的实例,用lock1也是一样的。
结论:并行
public class SynchronizedObjectCodeBlock2 implements Runnable {
static SynchronizedObjectCodeBlock2 instance1 = new SynchronizedObjectCodeBlock2();
static SynchronizedObjectCodeBlock2 instance2 = new SynchronizedObjectCodeBlock2();
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
// t1.join();
// t2.join();
while(t1.isAlive() || t2.isAlive()) {}
System.out.println("finished");
}
@Override
public void run() {
synchronized (this) {
System.out.println("I'm object code block lock1 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm object code block lock1 " + Thread.currentThread().getName() + " is over");
}
// synchronized (lock2) {
// System.out.println("I'm object code block lock2 " + Thread.currentThread().getName());
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("I'm object code block lock2 " + Thread.currentThread().getName() + " is over");
// }
}
}
public class SynchronizedStaticMethod4 implements Runnable {
static SynchronizedStaticMethod4 instance1 = new SynchronizedStaticMethod4();
static SynchronizedStaticMethod4 instance2 = new SynchronizedStaticMethod4();
public static void main(String[] args) {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
// t1.join();
// t2.join();
while(t1.isAlive() || t2.isAlive()) {}
System.out.println("finished");
}
@Override
public void run() {
method();
}
public static synchronized void method() {
System.out.println("I'm object method lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm object method lock " + Thread.currentThread().getName() + " is over");
}
}
结论:串行
结论当然是非同步方法不会受到影响
public class SynchronizedYesOrNo6 implements Runnable{
static SynchronizedYesOrNo6 instance = new SynchronizedYesOrNo6();
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
// t1.join();
// t2.join();
while(t1.isAlive() || t2.isAlive()) {}
System.out.println("finished");
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
System.out.println("I'm lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm lock " + Thread.currentThread().getName() + " is over");
}
public void method2() {
System.out.println("I'm not lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm not lock " + Thread.currentThread().getName() + " is over");
}
}
试想一下如果本该作为临界资源的变量i,除了在同步代码块内,还在普通方法的地方被修改,会发生什么呢?
public class DisappearRequest1 implements Runnable {
static DisappearRequest1 instance = new DisappearRequest1();
static int i = 0;
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
for(int j=0; j<100000; j++) {
i++;
}
}
public void method2() {
for(int j=0; j<100000; j++) {
i++;
}
}
}
i的最后结果是小于200000的…所以临界资源必须进行互斥操作。
public class SynchronizedDifferentMethod7 implements Runnable{
static SynchronizedDifferentMethod7 instance = new SynchronizedDifferentMethod7();
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
// t1.join();
// t2.join();
while(t1.isAlive() || t2.isAlive()) {}
System.out.println("finished");
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
System.out.println("I'm lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm lock " + Thread.currentThread().getName() + " is over");
}
public synchronized void method2() {
System.out.println("I'm not lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm not lock " + Thread.currentThread().getName() + " is over");
}
}
结论串行:其实相当于是synchronized锁了同一个this对象
预测:并行
public class SynchronizedStaticAndNormal8 implements Runnable{
static SynchronizedStaticAndNormal8 instance = new SynchronizedStaticAndNormal8();
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
// t1.join();
// t2.join();
while(t1.isAlive() || t2.isAlive()) {}
System.out.println("finished");
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public static synchronized void method1() {
System.out.println("I'm static lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm static lock " + Thread.currentThread().getName() + " is over");
}
public synchronized void method2() {
System.out.println("I'm not static " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm not static " + Thread.currentThread().getName() + " is over");
}
}
结论:并行
原因:static加锁的对象是该类的类类型,而普通方法锁加锁的对象是this,这显然是两把不同的锁。
要使用RuntimeException来抛出异常
public class SynchronizedException9 implements Runnable {
static SynchronizedException9 instance = new SynchronizedException9();
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
// t1.join();
// t2.join();
while(t1.isAlive() || t2.isAlive()) {}
System.out.println("finished");
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
System.out.println("I'm static lock " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
// throw new Exception();
} catch (InterruptedException e) {
e.printStackTrace();
}
// catch (Exception e) {
// e.printStackTrace();
// }
throw new RuntimeException();
// System.out.println("I'm static lock " + Thread.currentThread().getName() + " is over");
}
public synchronized void method2() {
System.out.println("I'm not static " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I'm not static " + Thread.currentThread().getName() + " is over");
}
}