问题:以下四个程序doOther方法的执行需不需要等待doSome方法的结束?
程序1:
public class Exam01 {
public static void main(String[] args) {
Myclass mc1 = new Myclass();
Myclass mc2 = new Myclass();
Thread t1 = new MyThread(mc1);
Thread t2 = new MyThread(mc2);
t1.setName("t1");
t2.setName("t2");
t1.start();
//睡眠的目的保证t1先执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
class MyThread extends Thread{
private Myclass mc;
public MyThread(Myclass mc){
this.mc = mc;
}
@Override
public void run(){
if(Thread.currentThread().getName().equals("t1")){
Myclass.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
Myclass.doOther();
}
}
}
class Myclass{
public synchronized static void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public synchronized static void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
关于程序1,是需要的,因为synchronized是写在静态方法里面的,所以此时synchronized是类锁,不管创建几个对象,一个类只能有一个锁,所以需要等待
程序2:
public class Exam01 {
public static void main(String[] args) {
Myclass mc1 = new Myclass();
Myclass mc2 = new Myclass();
Thread t1 = new MyThread(mc1);
Thread t2 = new MyThread(mc2);
t1.setName("t1");
t2.setName("t2");
t1.start();
//睡眠的目的保证t1先执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
class MyThread extends Thread{
private Myclass mc;
public MyThread(Myclass mc){
this.mc = mc;
}
@Override
public void run(){
if(Thread.currentThread().getName().equals("t1")){
mc.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
mc.doOther();
}
}
}
class Myclass{
public synchronized void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public synchronized void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
关于程序2,不需要等待,因为Myclass有两个对象,两个对象有两把锁,一个锁对应一个synchronized,所以t1和t2各自执行各自的,不受睡眠影响
程序3:
public class Exam01 {
public static void main(String[] args) {
Myclass mc = new Myclass();
Thread t1 = new MyThread(mc);
Thread t2 = new MyThread(mc);
t1.setName("t1");
t2.setName("t2");
t1.start();
//睡眠的目的保证t1先执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
class MyThread extends Thread{
private Myclass mc;
public MyThread(Myclass mc){
this.mc = mc;
}
@Override
public void run(){
if(Thread.currentThread().getName().equals("t1")){
mc.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
mc.doOther();
}
}
}
class Myclass{
public synchronized void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public synchronized void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
关于程序3,需要,因为,Myclass对象只有一个,且doOther和doSome都有synchronized,所以只有当doSome执行完,doOther才能执行
程序4:
public class Exam01 {
public static void main(String[] args) {
Myclass mc = new Myclass();
Thread t1 = new MyThread(mc);
Thread t2 = new MyThread(mc);
t1.setName("t1");
t2.setName("t2");
t1.start();
//睡眠的目的保证t1先执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
class MyThread extends Thread{
private Myclass mc;
public MyThread(Myclass mc){
this.mc = mc;
}
@Override
public void run(){
if(Thread.currentThread().getName().equals("t1")){
mc.doSome();
}
if (Thread.currentThread().getName().equals("t2")){
mc.doOther();
}
}
}
class Myclass{
public synchronized void doSome(){
System.out.println("doSome begin");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("doSome over");
}
public void doOther(){
System.out.println("doOther begin");
System.out.println("doOther over");
}
}
关于程序4 不需要等待,因为doOther没有synchronized。
本文通过四个程序示例分析了Java中synchronized关键字在静态方法和实例方法中应用的区别。在程序1和程序3中,由于静态方法的同步是基于类锁,因此doOther方法的执行需要等待doSome方法结束。而在程序2中,由于doSome和doOther是实例方法,每个对象有自己的锁,因此两个线程可以并发执行,不需等待。程序4中,doOther未使用synchronized,故也不需要等待。这些示例展示了Java多线程同步的微妙之处。
1959





