关于多线程生产者与消费者的疑问

changliushun 2017-02-14 12:33:56
下面代码简单模拟了一下生产者与消费者的最简单的例子

1为什么加上了synchronized但还是无法同步。结果会有偏差?

2为什么在pop 和 push方法上加 static 可以完成同步?

3不在pop,push方法上加static 怎样完成同步?


public class TestProducerConsumer {
public static void main(String[] args) throws InterruptedException {
for(int i=0;i<9;i++){
new Push().start();
}

for(int i=0;i<3;i++){
new Pop().start();
}


//睡眠以保证 上面的线程都执行完毕
Thread.sleep(500);

System.out.println(Synch.currentId);
}
}

//调用pop的线程类
class Pop extends Thread{
@Override
public void run() {
try {
new Synch().pop(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
//调用push的线程类
class Push extends Thread{
@Override
public void run() {
try {
new Synch().push(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

//设计同步的类
class Synch{

public static int currentId = 1;
//负责把currentId --,中间睡眠2毫秒 来测试别的线程是否会干扰
public synchronized void pop(String name) throws InterruptedException{
int temp = currentId;
temp--;

Thread.sleep(2);
System.out.println(name+"--------");

currentId=temp;
}

//负责把currentId ++,中间睡眠6毫秒 来测试别的线程是否会干扰
public synchronized void push(String name) throws InterruptedException{
int temp = currentId;
temp++;

Thread.sleep(6);

System.out.println(name+"+++++++++");
currentId=temp;
}
}

...全文
98 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
李德胜1995 2017-02-14
  • 打赏
  • 举报
回复
synchronized修饰非静态方法是对象锁,修饰静态方法是类锁,你代码中连个Synch对象不同,所以修饰非静态方法是锁不住的
changliushun 2017-02-14
  • 打赏
  • 举报
回复
引用 4 楼 pany1209 的回复:
[quote=引用 2 楼 changliushun 的回复:] [quote=引用 1 楼 pany1209 的回复:] synchronized修饰非静态方法是对象锁,修饰静态方法是类锁,你代码中连个Synch对象不同,所以修饰非静态方法是锁不住的
明白了一些,也就是说,这种调用的方法(多对象),除了用static没有修改的余地 [/quote]使用同一个对象就能锁住
private Synch synch;
    public Pop(Synch synch) {
		this.synch = synch;
	}
[/quote] 非常感谢,我再屡屡思路
李德胜1995 2017-02-14
  • 打赏
  • 举报
回复
引用 2 楼 changliushun 的回复:
[quote=引用 1 楼 pany1209 的回复:] synchronized修饰非静态方法是对象锁,修饰静态方法是类锁,你代码中连个Synch对象不同,所以修饰非静态方法是锁不住的
明白了一些,也就是说,这种调用的方法(多对象),除了用static没有修改的余地 [/quote]使用同一个对象就能锁住
private Synch synch;
    public Pop(Synch synch) {
		this.synch = synch;
	}
李德胜1995 2017-02-14
  • 打赏
  • 举报
回复
不加static完成同步要使用同一个Synch对象
Synch synch=new Synch();
        for(int i=0;i<9;i++){
            new Push(synch).start();
        }
         
        for(int i=0;i<3;i++){
            new Pop(synch).start();
        }
         
 
        //睡眠以保证 上面的线程都执行完毕
        Thread.sleep(500);
         
        System.out.println(Synch.currentId);
changliushun 2017-02-14
  • 打赏
  • 举报
回复
引用 1 楼 pany1209 的回复:
synchronized修饰非静态方法是对象锁,修饰静态方法是类锁,你代码中连个Synch对象不同,所以修饰非静态方法是锁不住的
明白了一些,也就是说,这种调用的方法(多对象),除了用static没有修改的余地

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧