本节主类与资源类如下:
class Resorce{ //资源
static int x=0;
static int y=0;
}
public class Main {
public static void main(String[] args) {
Operate op=new Operate();
Thread t1=new Thread() {
public void run() {
op.fun1();
}
};
Thread t2=new Thread() {
public void run() {
op.fun2();
}
};
t1.start();
t2.start();
}
}
2.1 两个非static方法,一个被synchronized修饰,一个未被修饰,能否并发?(能并发)
(本例中两个方法访问同一资源,能并发;若访问不同资源,也能并发)
class Operate{
void fun1() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t1-uux:"+Resorce.x);
}
}
synchronized void fun2() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t2-sux:"+Resorce.x);
}
}
}
运行结果:
t1-sux:2
t2-uux:2
t2-uux:4
t1-sux:3
t1-sux:6
t2-uux:5
sux:被synchronized修饰,未被static修饰,资源为x;
uux:未被synchronized修饰,未被static修饰,资源为x。
2.2 两个非static方法,都被synchronized修饰,能否并发?(不能并发)
(本例中两个方法访问不同资源,不能并发;若访问同一资源,也不能并发)
class Operate{
synchronized void fun1() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t1-sux:"+Resorce.x);
}
}
synchronized void fun2() {
for(int i=0;i<3;i++) {
Resorce.y++;
for(int j=0;j<1000;j++); //延时
System.out.println("t2-suy:"+Resorce.y);
}
}
}
运行结果:
t1-sux:1
t1-sux:2
t1-sux:3
t2-suy:1
t2-suy:2
t2-suy:3
sux:被synchronized修饰,未被static修饰,资源为x;
suy:被synchronized修饰,未被static修饰,资源为y。
2.3 两个synchronized方法,一个被static修饰,一个未被修饰,能否并发?(能并发)
(本例中两个方法访问同一资源,能并发;若访问不同资源,也能并发)
class Operate{
synchronized void fun1() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t1-sux:"+Resorce.x);
}
}
synchronized static void fun2() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t2-ssx:"+Resorce.x);
}
}
}
运行结果:
t1-ssx:2
t1-ssx:3
t2-sux:2
t1-ssx:4
t2-sux:5
t2-sux:6
ssx:被synchronized修饰,被static修饰,资源为x;
sux:被synchronized修饰,未被static修饰,资源为x。
2.4 两个static方法,都被synchronized修饰,能否并发?(不能并发)
(本例中两个方法访问不同资源,不能并发;若访问同一资源,也不能并发)
class Operate{
synchronized static void fun1() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t1-ssx:"+Resorce.x);
}
}
synchronized static void fun2() {
for(int i=0;i<3;i++) {
Resorce.y++;
for(int j=0;j<1000;j++); //延时
System.out.println("t2-ssy:"+Resorce.y);
}
}
}
运行结果:
t1-ssx:1
t1-ssx:2
t1-ssx:3
t2-ssy:1
t2-ssy:2
t2-ssy:3
ssx:被synchronized修饰,被static修饰,资源为x;
ssy:被synchronized修饰,被static修饰,资源为y。
针对第2节中的两种不能并发的情况进行讨论,主类和资源类如下:
class Resorce{ //临界资源
static int x=0;
static int y=0;
}
public class Main {
public static void main(String[] args) {
Operate op1=new Operate();
Operate op2=new Operate();
Thread t1=new Thread() {
public void run() {
op1.fun1();
}
};
Thread t2=new Thread() {
public void run() {
op2.fun2();
}
};
t1.start();
t2.start();
}
}
3.1 两个非static方法,都被synchronized修饰,能否并发?(能并发)
(本例中两个方法访问同一资源,能并发;若访问不同资源,也能并发)
class Operate{
synchronized void fun1() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t1-sux:"+Resorce.x);
}
}
synchronized void fun2() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t2-sux:"+Resorce.x);
}
}
}
运行结果:
t2-sux:2
t1-sux:2
t1-sux:4
t1-sux:5
t2-sux:3
t2-sux:6
sux:被synchronized修饰,未被static修饰,资源为x。
3.2 两个static方法,都被synchronized修饰,能否并发?(不能并发)
(本例中两个方法访问不同资源,不能并发;若访问同一资源,也不能并发)
class Operate{
synchronized static void fun1() {
for(int i=0;i<3;i++) {
Resorce.x++;
for(int j=0;j<1000;j++); //延时
System.out.println("t1-ssx:"+Resorce.x);
}
}
synchronized static void fun2() {
for(int i=0;i<3;i++) {
Resorce.y++;
for(int j=0;j<1000;j++); //延时
System.out.println("t2-ssy:"+Resorce.y);
}
}
}
运行结果:
t1-ssx:1
t1-ssx:2
t1-ssx:3
t2-ssy:1
t2-ssy:2
t2-ssy:3
ssx:被synchronized修饰,被static修饰,资源为x;
ssy:被synchronized修饰,被static修饰,资源为y。
这里的资源不是临界资源,临界资源由信号量来控制其访问。