当前位置: 代码迷 >> J2SE >> 多线程一个代码有些疑惑
  详细解决方案

多线程一个代码有些疑惑

热度:24   发布时间:2016-04-23 20:34:05.0
多线程一个代码有点疑惑
class Ticket implements Runnable{
private int tnum=100;
boolean flag=true;
public  void run(){
if(flag){
.         .......  else.......(两个执行内容我就不复制了)
public class sy{
public static void main(String[] args){
Ticket t=new Ticket();
Thread t1=new Thread(t);
Thread t2=new Thread(t);

t1.start();
try{Thread.sleep(10);}catch(Exception e){}
t.flag=false;
t2.start();
当主线程运行完后为什么t2的flag变成flase而t1的flag却是true。为什么不都是false呢主线程都运行结束了t。flag也改了才对啊  求指导
------解决方案--------------------
主线程结束掉了,子线程也会结束的
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

主线程结束掉了,子线程也会结束的

当然子线程必须是守护线程。

1.main所在的线程结束,和其它子线程是否结束没有任何关系。
2.main所在的线程结束,demon线程是否退出也和它没有任何关系,而是看整个jvm进程内是否还有非
demon线程,如果没有,整个jvm进程退出。换句话说jvm只要发现不再有非demon线程就退出,main线程是否退出没有任何关系。

新手感觉太绕了,来个通俗点的。
线程分为,守护线程和用户线程。
守护线程就是为了守护他的主人(启动他的线程)的,主人死了他也得陪葬,天台见!
用户线程就是各玩各的,主人死了也没他啥事儿,该吃吃该喝喝,除非天塌了(jvm挂了)!


最后2点
1. 由守护线程启动的线程,也是守护线程
2. 由用户线程启动的线程,也是用户线程
3. 默认情况下启动的线程,不是守护线程

高手,学习了,膜拜,是我等的偶像!!
------解决方案--------------------
引用:
看不太懂啊 我刚看到线程  能不能分析下为什么t.flag=false后      t1是还是true,看书去- -


t1,t2,和main线程都在同时抢夺资源,等待cpu将他们安排到执行序列中去,所以你最初的代码无法保证执行的顺序。

你的程序t1打印了flag=true,t2打印了flag=false的情况,是由于你让main线程Thread.sleep(xxx)了,这时候,t1就有机会去抢cpu(因为main线程休息了那么一小会儿),否则的话,很可能t1还没来得及执行,main线程就已经将flag设置成false了!

就是说,可能这一小短时间,t1.start()进入runnable状态,开始准备执行,这时候main线程抢到资源,执行了t.flag=false,然后cpu又转会t1线程执行,此时flag就已经是false了,然后cpu又转到t2去执行


另外,
t.flag = false; // 这个是main线程设置的,但是你不能肯定他就会在t1线程执行完毕以后才执行!

你要保证t1线程执行完毕才执行main的这个t.flag = false的话,单靠Thread.sleep(xxx)是不准确的。

可以使用t1.join()来安插t1到main线程中(意思就是t1先执行完毕,再继续执行main线程剩下的部分),在你的基础上稍微改了一下。希望能有所帮助。


class Ticket implements Runnable {
    private int tnum = 100;
    boolean flag = true;

    public synchronized void foo(){
        for(int i=0;i<10;i++)
        System.out.println(Thread.currentThread().getName() + " " + this.flag);
    }
    
    public void run() {
        foo();
    }
}

public class Test {
    public static void main(String[] args) {
        Ticket t = new Ticket();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);

        t1.start();
        try {
            t1.join(); // t1被安插到main线程中了,只有t1执行完毕,main线程才会继续执行剩下的部分
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        try {
//            Thread.sleep(10);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
         t.flag=false;
         t2.start();
    }
}

  相关解决方案