JUC线程进阶篇08:线程中常见的8中用锁情况
标签: 多线程
在工作用,多线程中对是否加上synchronized,是否加上static等,8种常见的用锁的情况
8种情况
题目
判断打印的”one” or “two”??
1.两个普通同步方法,两个线程,标准打印,结果:one two
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
}
}
class Number{
public synchronized void getOne(){
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("Two");
}
}
2.新增Thread.sleep()给getOne(),结果:one two
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
}
}
class Number{
public synchronized void getOne(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("Two");
}
}
3.新增普通方法getThree(),结果:three one two
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getTwo();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number.getThree();
}
}).start();
}
}
class Number{
public synchronized void getOne(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("Two");
}
public void getThree(){
System.out.println("Three");
}
}
4.两个普通同步方法,两个对象,结果:two one
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number1 = new Number();
final Number number2 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number1.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number2.getTwo();
}
}).start();
}
}
class Number{
public synchronized void getOne(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("Two");
}
}
5.修改getOne()为静态同步方法,结果:two one
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number1 = new Number();
final Number number2 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number1.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number2.getTwo();
}
}).start();
}
}
class Number{
public static synchronized void getOne(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("Two");
}
}
6.修改两个方法均为静态同步方法,一个对象,结果:one two
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number1 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number1.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number1.getTwo();
}
}).start();
}
}
class Number{
public static synchronized void getOne(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public static synchronized void getTwo(){
System.out.println("Two");
}
}
7.一个静态同步方法,一个非静态同步方法,两个对象,结果:two one
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number1 = new Number();
final Number number2 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number1.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number2.getTwo();
}
}).start();
}
}
class Number{
public static synchronized void getOne(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public synchronized void getTwo(){
System.out.println("Two");
}
}
8.两个静态同步方法,两个对象,结果:one two
public class TestThread8Monitor {
public static void main(String[] args) {
final Number number1 = new Number();
final Number number2 = new Number();
new Thread(new Runnable() {
@Override
public void run() {
number1.getOne();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
number2.getTwo();
}
}).start();
}
}
class Number{
public static synchronized void getOne(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("one");
}
public static synchronized void getTwo(){
System.out.println("Two");
}
}
总结
其实这八种用法的区别关键在于以下两点:
非静态方法的锁默认为this,静态方法的锁为对应的class实例(这里是NUmber.class)
某一个时刻内,只能有一个线程持有锁,无论有几个方法