新手请问关于JAVA用synchronized限制多个进程同时访问同一个资源?

时间:2022-09-28 11:18:19
小弟刚学到JAVA的多线程,有点不明白里面的synchronized 关键字的用法。
public class Q7 extends Thread {
public synchronized void f1() {
System.out.println("f1()");
try {
sleep(2000);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("after 2 second");
return;
}

public static void main(String[] args) {
//创建并运行第一个线程
new Thread() {
public void run() {
Q7 test = new Q7();
System.out.println(getName());
test.f1();
}
}.start();

//创建并运行第二个线程
new Thread() {
public void run() {
Q7 test = new Q7();
System.out.println(getName());
test.f1();
}
}.start();
}
}


运行结果是:
Thread-0
f1()
Thread-1
f1()
after 2 second
after 2 second

这里的f1()用了synchronized关键字,不是应该要等到Thread-0运行完f1()后才会让Thread-1调用f1()的吗?求赐教!

12 个解决方案

#1


恩 其实就是为了防止多线程访问共享资源脏读,基本类似信号量,但在同步时仍然可以使用wait()方法把资源让出去等等,你看下下面的解释吧
http://baike.baidu.com/view/1207212.htm?fr=ala0_1

#2


启动的是Thread的start,new的是Q7的test...和
我有点儿蒙

#3


每个对象都有一个锁
public synchronized void f1()   //这里的锁是this  ,当一个线程获得锁之后进入方法体,其它线程只能等待释放锁,从而获得锁。说白点就是某一时刻只能有一个线程进入f1()方法

#4


引用 3 楼 wzju64676266 的回复:
每个对象都有一个锁
 public synchronized void f1()   //这里的锁是this  ,当一个线程获得锁之后进入方法体,其它线程只能等待释放锁,从而获得锁。说白点就是某一时刻只能有一个线程进入f1()方法

对啊,Thread-0 运行f1()至少要两秒,那么Thread-1应该是要2秒后才会运行f1()的,但现在是两个线程几乎是同时调用f1()的(Thread-1没等Thread-0的f1() sleep(2000)完就调用f1()了)

#5


 public synchronized void f1() {

是实例级别的锁,而你的2个线程里都有
 Q7 test = new Q7();

也就是每个线程都是独立的实例,当然他们不使用一个锁了。

解决方法有2个
1 多个线程用一个 Q7 test
2 把方法改成
 public static synchronized void f1() {

#6


你的 test 实例了两次啊 已经不是同一个共享资源了 他们在内存中的地址就不一样  这好像和锁没关系
你试试看只实例化一次看看
public class Q7 extends Thread {
public synchronized void f1() {
System.out.println("f1()");
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after 2 second");
return;
}

public static void main(String[] args) {
// 创建并运行第一个线程
final Q7 test=new Q7();
new Thread() {
public void run() {
System.out.println(getName());
test.f1();
}
}.start();
// 创建并运行第二个线程
new Thread() {
public void run() {
System.out.println(getName());
test.f1();
}
}.start();
}
}
 
这样就对了

#7


看了楼主的程序
敢问楼主为什么要 Q7 extends Thread?
Q7继承 extends Thread 作用何在??

个人觉得这道题目很有探讨的价值

#8


引用 5 楼 java2000_net 的回复:
public synchronized void f1() {

 是实例级别的锁,而你的2个线程里都有
  Q7 test = new Q7();

 也就是每个线程都是独立的实例,当然他们不使用一个锁了。

 解决方法有2个
 1 多个线程用一个 Q7 test
 2 把方法改成
  public static synchronized void f1() {


老紫竹果然厉害啊

#9


你那就是俩不同的Q7对象,何来锁一说?

#10


引用 3 楼 wzju64676266 的回复:
每个对象都有一个锁
public synchronized void f1()  //这里的锁是this  ,当一个线程获得锁之后进入方法体,其它线程只能等待释放锁,从而获得锁。说白点就是某一时刻只能有一个线程进入f1()方法


upup

#11


同步是针对同一个对象而言的。

#12


路过。同步,等待还需参考

#1


恩 其实就是为了防止多线程访问共享资源脏读,基本类似信号量,但在同步时仍然可以使用wait()方法把资源让出去等等,你看下下面的解释吧
http://baike.baidu.com/view/1207212.htm?fr=ala0_1

#2


启动的是Thread的start,new的是Q7的test...和
我有点儿蒙

#3


每个对象都有一个锁
public synchronized void f1()   //这里的锁是this  ,当一个线程获得锁之后进入方法体,其它线程只能等待释放锁,从而获得锁。说白点就是某一时刻只能有一个线程进入f1()方法

#4


引用 3 楼 wzju64676266 的回复:
每个对象都有一个锁
 public synchronized void f1()   //这里的锁是this  ,当一个线程获得锁之后进入方法体,其它线程只能等待释放锁,从而获得锁。说白点就是某一时刻只能有一个线程进入f1()方法

对啊,Thread-0 运行f1()至少要两秒,那么Thread-1应该是要2秒后才会运行f1()的,但现在是两个线程几乎是同时调用f1()的(Thread-1没等Thread-0的f1() sleep(2000)完就调用f1()了)

#5


 public synchronized void f1() {

是实例级别的锁,而你的2个线程里都有
 Q7 test = new Q7();

也就是每个线程都是独立的实例,当然他们不使用一个锁了。

解决方法有2个
1 多个线程用一个 Q7 test
2 把方法改成
 public static synchronized void f1() {

#6


你的 test 实例了两次啊 已经不是同一个共享资源了 他们在内存中的地址就不一样  这好像和锁没关系
你试试看只实例化一次看看
public class Q7 extends Thread {
public synchronized void f1() {
System.out.println("f1()");
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after 2 second");
return;
}

public static void main(String[] args) {
// 创建并运行第一个线程
final Q7 test=new Q7();
new Thread() {
public void run() {
System.out.println(getName());
test.f1();
}
}.start();
// 创建并运行第二个线程
new Thread() {
public void run() {
System.out.println(getName());
test.f1();
}
}.start();
}
}
 
这样就对了

#7


看了楼主的程序
敢问楼主为什么要 Q7 extends Thread?
Q7继承 extends Thread 作用何在??

个人觉得这道题目很有探讨的价值

#8


引用 5 楼 java2000_net 的回复:
public synchronized void f1() {

 是实例级别的锁,而你的2个线程里都有
  Q7 test = new Q7();

 也就是每个线程都是独立的实例,当然他们不使用一个锁了。

 解决方法有2个
 1 多个线程用一个 Q7 test
 2 把方法改成
  public static synchronized void f1() {


老紫竹果然厉害啊

#9


你那就是俩不同的Q7对象,何来锁一说?

#10


引用 3 楼 wzju64676266 的回复:
每个对象都有一个锁
public synchronized void f1()  //这里的锁是this  ,当一个线程获得锁之后进入方法体,其它线程只能等待释放锁,从而获得锁。说白点就是某一时刻只能有一个线程进入f1()方法


upup

#11


同步是针对同一个对象而言的。

#12


路过。同步,等待还需参考