public class mainfile { static int num = 5000; public static void main(String[] args) throws InterruptedException {
myThreadClass1 thread1 = new myThreadClass1();
myThreadClass2 thread2 = new myThreadClass2(); Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2); t1.setPriority(4);
t2.setPriority(4); t1.start();
t2.start(); }
}class myThreadClass1 implements Runnable { myThreadClass1() { } public synchronized void run() {
System.out.println("Created thread"); while (mainfile.num > 0) {
mainfile.num--;
System.out.println("thread 1:sell 1.leaving:" + mainfile.num + ";");
}
}
}class myThreadClass2 implements Runnable { myThreadClass2() { } public synchronized void run() {
System.out.println("Created thread"); while (mainfile.num > 0) {
mainfile.num--;
System.out.println("thread 2:sell 1.leaving:" + mainfile.num + ";"); }
}}
执行结果中为什么1线程和2线程轮流切换访问资源,而不是1进程执行完后执行2进程。
另外输出剩余数量时,为什么有的剩余数量会滞后输出。

解决方案 »

  1.   

    把run()前面的synchronized 去掉
      

  2.   

    synchronized 不是用在Thread的run方法前面的,我没见过这种写法synchronized是对对象或类(静态)而言,当synchronized对一个对象的方法或对象变量加锁时,这个对象仅可以被一个线程访问。另外:你的num是个静态共享的变量。你有两个线程,启动后是独立的,所以1线程和2线程轮流切换访问资源,而不是1进程执行完后执行2进程。 
      

  3.   

    另外想知道synchronized怎么使用。我之间是学C/C++的,没见过这个修饰符。
      

  4.   

    还有JAVA中的线程同步有哪些?
      

  5.   

    好好理解下线程的概念吧,问这个问题说明你没搞清什么是线程。
    在你的程序执行的过程成会产生一个mainfile 进程。在这个进程中你有创建了两个线程。
    线程的执行是并行的而不是你理解串行。在有先级相同的情况下,执行那个取决与操作系统的选择。
      

  6.   

    线程的概念我了解,我主要是不会用JAVA中线程同步的方法。也主要是为了线程同步。
      

  7.   

    不好意思,刚才看错了。
    你这是创建了两个独立的线程,虽然访问的是统一个资源。但是每个线程是在自己的方法中调用的,对与不同的线程来说,他们访问的都是自己的资源,没有同步的问题。把函数改成这样就会存在同步问题了。
       static int num = 5000;    public static void main(String[] args) throws InterruptedException {
            myThreadClass1 thread1 = new myThreadClass1();
            //myThreadClass1 thread2 = new myThreadClass2();         Thread t1 = new Thread(thread1);
            Thread t2 = new Thread(thread1);        t1.setPriority(4);
            t2.setPriority(4);        t1.start();
            t2.start();    }
      

  8.   

    我也正在学习,是不是这样呢:
    synchronized有两种使用方法,一种是synchronized(对象){}代码块,那个小括号里的对象就是“索旗标”,当一个线程执行该代码块时,它将索旗标关闭,其他线程无法执行这段代码。当这个执行完这段代码时,将索旗标打开,这时其他线程就可以执行这段代码了,以此类推;
    另外一种就是在方法前面加“synchronized”。那么这个方法 就和上面那个代码块类似。不过这里的“索旗标”对应的对象是“this”对象。
    你上述的代码没有同步,是因为 两个run方法的索旗标分别是两个对象--分别是两个类中的this对象。而索旗标只有一个时才能起到作用。
      

  9.   

    将synchronized 去掉有用吗,试了一下,ms没用的。
    需要达到执行完线程1后再执行线程2,代码应改成如下这般:
    ps:以后记得类名首字母大写……public class mainfile {    static int num = 100;//5000; 改成100容易看得清楚一些    public static void main(String[] args) throws InterruptedException {
            mainfile main = new mainfile();        myThreadClass1 thread1 = new myThreadClass1(main);
            myThreadClass2 thread2 = new myThreadClass2(main);        Thread t1 = new Thread(thread1);
            Thread t2 = new Thread(thread2);        t1.setPriority(4);
            t2.setPriority(4);        t1.start();
            t2.start();    }    public synchronized void subtract(String id) {        while (mainfile.num > 0) {
                mainfile.num--;
                System.out.println("threadId: " + id + " num: " + mainfile.num + ";");
            }
            // 线程1完成后num变为0,为了让线程2也能正常执行,恢复它的初始值
            mainfile.num = 100;
        }
    }class myThreadClass1 implements Runnable {
        
        private mainfile main;
        myThreadClass1(mainfile main) {
            this.main = main;
        }    public void run() {
            System.out.println("Created thread");        this.main.subtract("id1");
        }
    }class myThreadClass2 implements Runnable {    private mainfile main;
        myThreadClass2(mainfile main) {
            this.main = main;
        }    public void run() {
            System.out.println("Created thread");        this.main.subtract("id2");
        }}
      

  10.   

    要实现两个不同的函数访问相同的资源实现同步操作,我想到两种方法:
    1:在这两个函数内部都定义一个synchronized代码块,使它们的索旗标是同一个对象;
    2:这两个函数放在同一个类中,那么它们的索旗标都是这个类中的"this"对象;
      

  11.   

    public class mainfile {    static int num = 100;    public static void main(String[] args) throws InterruptedException {
         String str = ""; //为两个类中的synchronized代码块提供同一个索旗标
            myThreadClass1 thread1 = new myThreadClass1(str);
            myThreadClass2 thread2 = new myThreadClass2(str);        Thread t1 = new Thread(thread1);
            Thread t2 = new Thread(thread2);        t1.start();
            t2.start();
     
        }
    }class myThreadClass1 implements Runnable { String str = null;
        myThreadClass1(String s1) {
         this.str = s1;
        }    public void run() {
         synchronized(str){
         System.out.println("Created thread");
         while (mainfile.num > 50) {
         mainfile.num--;
         System.out.println("thread 1:sell 1.leaving:" + mainfile.num + ";");
         }
         }
        
        }
    }class myThreadClass2 implements Runnable {
    String str = null;
        myThreadClass2(String s2) {
         this.str = s2;
        }    public void run() {
         synchronized(str){
            System.out.println("Created thread");        while (mainfile.num > 0) {
                mainfile.num--;
                System.out.println("thread 2:sell 1.leaving:" + mainfile.num + ";");
            }
         }
        }
    }
    看看是不是你的意思
      

  12.   

    synchronized 的机制,不是当这个方法执行时,它不允许别的方法执行吗?
      

  13.   

    使用synchronized修饰的目的是锁住对象,线程A和线程B为了达到同步的目的,他们之间必须共同拥有同一个对象C,如:class A implements Runnable{
       private C c;
       public A(C c){
          this.c = c;
       }
       public void run(){
          ......
          synchronized(c){
             ......
          }
          ......
       }
    }
    class B implements Runnable{
       private C c;
       public B(C c){
          this.c = c;
       }
       public void run(){
          ......
          synchronized(c){
             ......
          }
          ......
       }
    }class Test{
       public static void main(String []args){
          C c = new C();
          A a = new A(c);
          B b = new B(c);
          Thread t1 = new Thread(A); 
          Thread t2 = new Thread(B); 
          ......   }
    }这样A和B中存在同一对象c,当线程中使用
    synchronized(c){
             ......
          }
    这样的程序快,或者是调用了使用synchronized修饰的C的方法时,调用者就锁住了对象c,这时其它想要通过这种方法锁对象c的调用者,都会被暂停,直到第一个锁住对象的调用者释放c的锁(synchronized块执行完、c的同步方法执行2完或调用了c.wait()释放锁)为止,这样就达到了同步的目的。
      

  14.   

    我调试了下,好像没有达到同步的目的。1线程并没有把自身进行完,2线程还是读取了num。