请教一个关于线程访问共享变量的问题

NewDawn_C 2020-11-22 08:10:36
现在我有两个类,类A负责把发送标志位置为true,类B处于一直运行状态(因为要不断接收一些信息),然后当send_flag为true时类B要发送消息(这里我用打印语句表示)。下面是我给简化后的逻辑关系。
class A{
public static volatile boolean send_flag = false;
public void change(){
send_flag = true;
}
}

class B{
public void listen(){
while(true){
if(A.send_flag){
System.out.println("Hello");
}
}
}
}


然后我先运行B,然后在A中改变send_flag的值,为什么B中send_flag值一直都是false,一直打印不出来。volatile不是可以让变量具有可见性吗?我学习java没多久,还烦请各位学长学姐们指点一下。谢谢
...全文
2212 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
NewDawn_C 2020-11-23
  • 打赏
  • 举报
回复
引用 8 楼 新手村0617 的回复:
[quote=引用 5 楼 Mrzhuang007 的回复:]为什么我试了一下是可以的.

import java.util.concurrent.TimeUnit;

public class PrintThread {
    private static volatile boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if(flag) {
                        System.out.println("Success");
                        break;
                    }
                }
            }
        }).start();
        TimeUnit.SECONDS.sleep(5);
        System.out.println("设置为true");
        flag = true;
    }
}
正常输出: ---------- 设置为true Success
是的,这可以的[/quote] 我想把flag=true的语句放在另一个外部类中,用外部类的方法改变PrintThread类中while中的flag值,我试了下没成功
NewDawn_C 2020-11-23
  • 打赏
  • 举报
回复
引用 5 楼 Mrzhuang007 的回复:
为什么我试了一下是可以的.

import java.util.concurrent.TimeUnit;

public class PrintThread {
    private static volatile boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if(flag) {
                        System.out.println("Success");
                        break;
                    }
                }
            }
        }).start();
        TimeUnit.SECONDS.sleep(5);
        System.out.println("设置为true");
        flag = true;
    }
}
正常输出: ---------- 设置为true Success
如果把flag置为true的语句放在PrintThread之外的类还能行吗?我是有一个处理按键的类,用这个类把PrintThread里的flag置为true并打印出来
韩_师兄 2020-11-23
  • 打赏
  • 举报
回复
引用 5 楼 Mrzhuang007 的回复:
为什么我试了一下是可以的.

import java.util.concurrent.TimeUnit;

public class PrintThread {
    private static volatile boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if(flag) {
                        System.out.println("Success");
                        break;
                    }
                }
            }
        }).start();
        TimeUnit.SECONDS.sleep(5);
        System.out.println("设置为true");
        flag = true;
    }
}
正常输出: ---------- 设置为true Success
是的,这可以的
  • 打赏
  • 举报
回复
// if (收到数据) { flag = false; //这个睡眠是为了给时间让send看到标记变量已改变 sleep(1000); 加sleep试试
  • 打赏
  • 举报
回复
c语言是有互斥体(Mute)的方法 CreateMutex。多进程都可以控制。b线程等待信号,相当于暂停。a线程发信号,b线程继续运行,相当于不需要全局变量,而是用信号控制。还有可以用线程暂停继续的方法。b线程暂停,a线程让b线程继续运行
NewDawn_C 2020-11-22
  • 打赏
  • 举报
回复
引用 1 楼 亦夜 的回复:
你开启线程了吗?你应该是在main函数中调用的吧,线程可见性是指,你在线程中改变了值,对另一个线程是可见的 哪怕你不开启两条线程,你在main函数中也需要开启另一个线程来调用B的监听函数
线程我在B中的main函数里开启了,我写的方法是在线程里运行的,忘记写main了。 主要是想用A来改变B中的变量,然后让B中正在运行着的线程获取到flag的最新值。我在网上查了好多方法,好像都是改变完变量以后再启动线程。不知道这个运行着的线程该怎么及时获取新值。
Mrzhuang007 2020-11-22
  • 打赏
  • 举报
回复
为什么我试了一下是可以的.

import java.util.concurrent.TimeUnit;

public class PrintThread {
    private static volatile boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if(flag) {
                        System.out.println("Success");
                        break;
                    }
                }
            }
        }).start();
        TimeUnit.SECONDS.sleep(5);
        System.out.println("设置为true");
        flag = true;
    }
}
正常输出: ---------- 设置为true Success
亦夜 2020-11-22
  • 打赏
  • 举报
回复
你开启线程了吗?你应该是在main函数中调用的吧,线程可见性是指,你在线程中改变了值,对另一个线程是可见的 哪怕你不开启两条线程,你在main函数中也需要开启另一个线程来调用B的监听函数
亦夜 2020-11-22
  • 打赏
  • 举报
回复
我的意思你应该在函数调用的时候单独开启另一个线程表示B的监听线程,先调用监听函数,让改线程处于一个监听状态,然后调用A的方法修改该变量之后由于可见性,那么此刻B是能够获取到send_flag的最新值的
qybao 2020-11-22
  • 打赏
  • 举报
回复
把你的线程调用的代码也贴出来看看,光你列出的这些代码来看没问题

51,411

社区成员

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

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