java多线程,不同runnable之间可以在运行时改变对方的静态成员变量吗?

say_yoo 2016-11-09 04:57:53
我想在主线程里启用两个线程,这两个线程采用两个不同实现的Runnable对象,记作A和B。我的意图是当采用B的线程运行完成后通知A线程,首先我尝试了如下设计:

class Run {

public static void main(String[] args) {
new Thread(new A()).start();
new Thread(new B()).start();
}
}

class A implements Runnable {
public static volatile boolean isStop = false; // 标记B是否完成运行

public void run() {
while(! isStop) { //B结束后A跳出循环
do sth;
}
System.out.println("B has stopped.")
}
}

class B implements Runnable {

public void run() {
do sth;
A.isStop = true; // 准备退出,将A中的标志变量改为true
}
}

然而之后在启动这两个线程后,B结束后A仍在循环,即A读到的isStop依然为false.

之后我尝试将isStop变量改到main方法所在类中,大体设计如下:

class Run {
public static volatile boolean isStop = false; // 标记B是否完成运行

public static void main(String[] args) {
new Thread(new A()).start();
new Thread(new B()).start();
}
}

class A implements Runnable {

public void run() {
while(! Run.isStop) { //B结束后A跳出循环
do sth;
}
System.out.println("B has stopped.")
}
}

class B implements Runnable {
public void run() {
do sth;
Run.isStop = true; // 准备退出,将Run中的标志变量改为true
}
}

这样可以正常完成通知过程。但我不明白为什么会是这个结果?原理上跟先前的尝试有何不同?

提前谢过大家!
...全文
639 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
imsorry000 2016-11-10
  • 打赏
  • 举报
回复
package v_2.socket;

public class Run {
     
    public static void main(String args[]) {
    	Object lock=new Object();
        Thread a=new Thread(new A(lock));
        Thread b=new Thread(new B(lock));
        a.setName("a");
        b.setName("b");
        a.start();
        b.start();

    }
}
 
class A implements Runnable {
    //public static volatile boolean isStop = false; // 标记B是否完成运行
     Object lock;
     public  A(Object o){
    	 this.lock=o;
     }
    public void run() {
       /* while(! isStop) { //B结束后A跳出循环
            do sth;
        }
        System.out.println("B has stopped.")*/
    	synchronized(lock){
    		if(Thread.currentThread().getName().equals("a")){
    			try {
					lock.wait();//a等等,让b来通知它来运行
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
    		}
    		System.out.println("B has stopped.");
    	}
    }
}
 
class B implements Runnable {
   
   /* public void run() {
       do sth;
       A.isStop = true; // 准备退出,将A中的标志变量改为true
    }*/
	Object lock;
    public  B(Object o){
   	 	this.lock=o;
    }
	@Override
	public void run() {
		synchronized(lock){
			System.out.println("我是B线程 ,我现在运行!");
			System.out.println("我现在运行完啦,叫A运行...");
			lock.notifyAll();//lock.notifyAll();假如是多条线程
			
		}
	}
}
我是B线程 ,我现在运行!
我现在运行完啦,叫A运行...
B has stopped.
再不斩 2016-11-10
  • 打赏
  • 举报
回复
静态变量在A里也可以正常结束,你是怎么操作导致结束不了的?
自由自在_Yu 2016-11-10
  • 打赏
  • 举报
回复
两个运行结果应该是一致的吧。 因为先创建的A进程,所以会先执行A进程一段时间,然后执行B进程,执行B进程时把isStop 设置为true之后,再执行A进程,就会停止。这时就不会执行A进程了。 A run ... A run A run B run A run B has stopped. ------------------------- A run ... A run B run B has stopped. 运行会出现以上两种可能,对于第一种,是因为B进程设置isStop=true,中间的时间间隔可以让 A进程继续执行一次,所以B进程执行后,A又执行了一次 对于第二种则是时间间隔不够A继续执行,就被isStop=true这个条件终止了。 这是我的理解,希望对你有用
ipqtjmqj 2016-11-10
  • 打赏
  • 举报
回复
可以,我试了你第1种代码,也可结束
say_yoo 2016-11-10
  • 打赏
  • 举报
回复
引用 1 楼 LIANG576412610 的回复:
你的两个A是不同的实例
抱歉能麻烦再说详细些吗,确实是不同实例,在Run的main方法里启动线程
say_yoo 2016-11-10
  • 打赏
  • 举报
回复
抱歉能麻烦再说详细些吗,确实是不同实例,在Run的main方法里启动线程
LIANG576412610 2016-11-09
  • 打赏
  • 举报
回复
你的两个A是不同的实例

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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