java多线程中的一个问题。变量赋值无效,大神们看过来

JAVA-上帝之手 2018-09-02 10:13:16
java多线程中的一个问题。变量赋值无效,int mynum=(index+4);当index=15,,mynum却得到的是 9

package my_tesyt;

class NumberCla{
private String threadName;
int index = 0;;
int[] num=new int[75];
int rows=0;
public NumberCla(int[] num){
this.num=num;
}
public void print1(){
synchronized (this) {
int mynum=(index+4);
int last=num[mynum];
int threadnum=(((last/5)%3)==0?3:(last/5)%3);
while(threadnum!=1){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
int temp=index;
if(index<74){
for(int i=index;i<num.length;i++){
System.out.println(num[i]);
rows++;
System.out.println("打印行数:"+rows);
index++;
if(index-temp==5){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

}
}

public void print2(){
synchronized (this) {
int mynum=(index+4);
int last=num[mynum];
int threadnum=(((last/5)%3)==0?3:(last/5)%3);
while(threadnum!=2){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
int temp=index;
if(index<74){
for(int i=index;i<num.length;i++){
System.out.println(num[i]);
rows++;
System.out.println("打印行数:"+rows);
index++;
if(index-temp==5){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}

public void print3(){
synchronized (this) {
int mynum=(index+4);
int last=num[mynum];
int threadnum=(((last/5)%3)==0?3:(last/5)%3);
while(threadnum!=3){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
int temp=index;
if(index<74){
for(int i=index;i<num.length;i++){
System.out.println(num[i]);
rows++;
System.out.println("打印行数:"+rows);
index++;
if(index-temp==5){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}

class myThred1 extends Thread{
private NumberCla sync;
public myThred1(NumberCla sync){
this.sync=sync;
}
@Override
public void run() {
sync.print1();
}

}

class myThred2 extends Thread{
private NumberCla sync;
public myThred2(NumberCla sync){
this.sync=sync;
}
@Override
public void run() {
sync.print2();
}

}

class myThred3 extends Thread{
private NumberCla sync;
public myThred3(NumberCla sync){
this.sync=sync;
}
@Override
public void run() {
sync.print3();
}

}
public class Hellon{
public static void main(String[] args) {
int[] nums = new int[75];
for(int i=0;i<75;i++){
nums[i]=i+1;
}
NumberCla sync = new NumberCla(nums);

Thread t1=new myThred1(sync);
t1.setName("t1");
Thread t2=new myThred2(sync);
t2.setName("t2");
Thread t3=new myThred3(sync);
t3.setName("t3");
t1.start();
t2.start();
t3.start();




}
}
...全文
890 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
yql1986 2018-09-03
  • 打赏
  • 举报
回复
根据图片截图,当index=10时mynum=14,但此时mynum=9

当线程3抢到锁时,此时index=5,mynum=9,last变量=10,threadnum=2,while循环判断为假,执行wait这时会释放锁,线程3让出CPU,进入等待状态。此时线程1或2抢到锁后会执行index自增,当自增不符合条件时,线程1或2执行wait会释放锁,让出CPU,进入等待状态。锁被线程3抢到后恢复执行,这时你查看index变量为10,但是mynum=9。

你查看一下JDK中Object类wait方法注释,是恢复执行,不是从头开始执行,并不是重新开始执行print3方法,是从while判断变量那个位置恢复执行,mynum在前面已经赋值过了,index已经被其它线程更新过了。

















JAVA-上帝之手 2018-09-03
  • 打赏
  • 举报
回复
引用 2 楼 yql1986 的回复:
根据图片截图,当index=10时mynum=14,但此时mynum=9

当线程3抢到锁时,此时index=5,mynum=9,last变量=10,threadnum=2,while循环判断为假,执行wait这时会释放锁,线程3让出CPU,进入等待状态。此时线程1或2抢到锁后会执行index自增,当自增不符合条件时,线程1或2执行wait会释放锁,让出CPU,进入等待状态。锁被线程3抢到后恢复执行,这时你查看index变量为10,但是mynum=9。

你查看一下JDK中Object类wait方法注释,是恢复执行,不是从头开始执行,并不是重新开始执行print3方法,是从while判断变量那个位置恢复执行,mynum在前面已经赋值过了,index已经被其它线程更新过了。
回答的很正确,谢谢,,
JAVA-上帝之手 2018-09-02
  • 打赏
  • 举报
回复
具体的调试截图,,就是下面三个链接,,,,csdn没有显示出来

https://img-bbs.csdn.net/upload/201809/02/1535854249_970365.png
https://img-bbs.csdn.net/upload/201809/02/1535854263_595578.png
https://img-bbs.csdn.net/upload/201809/02/1535854272_581667.png

62,615

社区成员

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

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