不知道你写这段代码想测试的是什么功能。不过明显,你对多线程理解不够深入。synchronized同步的是对象,你在程序中创建了两个对象,作为两个线程去运行。同步方法没有起到对这两个线程的同步作用,输出有可能是
1线程:1
1线程:2
2线程:1
2线程:3
输出了两个1!

解决方案 »

  1.   

    在多线程中需要自增的时候,建议使用atomic下面的AtomicInteger等!
      

  2.   

    m1 与 m2 不是同一个对象 ,锁定对象,指的是锁定同一个对象,也就是说你这里只能用 m1 与 m2 中的一个
      

  3.   

    public class test1 {
    public static void main(String[] args) {
    myThread m1 = new myThread(1);
    myThread m2 = new myThread(2);
            new Thread(m1).start();
            new Thread(m2).start();
        }
    }
    class myThread implements Runnable{
    static Object o = new Object();
        static int i = 1;
        int k;
        myThread(int k){
            this.k = k;
        }
        synchronized public void run() {
            while(i <= 100){
                System.out.println(k + "线程:" + i);
                i++;
            }
        }
    }
    那如果这样呢?锁定了m1,想要锁定m2的时候但是不能访问o,所以锁定m1的时候m2应该拿不到锁吧?
      

  4.   

    Java code
    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class test1 {
        public static void main(String[] args) {
            myThread m1 = new myThread(1);
            myThread m2 = new myThread(2);
            new Thread(m1).start();
            new Thread(m2).start();
        }
    }
    class myThread implements Runnable{
        static Object o = new Object();
        static int i = 1;
        int k;
        myThread(int k){
            this.k = k;
        }
        synchronized public void run() {
            while(i <= 100){
                System.out.println(k + "线程:" + i);
                i++;
            }
        }
    }那如果这样呢?锁定了m1,想要锁定m2的时候但是不能访问o,所以锁定m1的时候m2应该拿不到锁吧?
      

  5.   

    1. 要执行synchronized声明的方法,必须要获得该方法所属的对象的锁。class MyHandler implements Runnable{
        int i = 0;
        public synchronized void run() {  // 需要获得MyHandler的某个实例的锁,才能进入这个方法
            i++;
            System.out.println(i);
        }
    }可以这么理解,就是把synchronized声明的方法(不一定是run方法,还可以是其他的)想象为一个房间(资源),如果有2个人(线程)都想进去,那么必须要有这个房间的钥匙(获得资源,并关上房门,即加锁)。如果1个人进去了,锁上了门,那么另外一个人就只能等待。
    MyHandler h1 = new MyHandler();
    Thread t1 = new Thread(h1); 
    Thread t2 = new Thread(h1);
    t1.start(); // t1可能获得了h1这个资源,并加了锁
    t2.start(); // t2 可能就只能等待了,因为他没有获得h1这个资源,无法加锁(锁门)
    区别MyHandler h1 = new MyHandler();
    MyHandler h2 = new MyHandler();
    Thread t1 = new Thread(h1); 
    Thread t2 = new Thread(h2);
    t1.start(); // t1可能获得了h1这个资源,并加了锁
    t2.start(); // t2 也可能获得了h2这个资源,并加了锁(因为h1和h2是两个资源,互相独立,所以t1和t2都可以各玩儿各的)2. 同步块其实也是相同的概念,不过比synchronized方法灵活一点(可以对任意的资源,不一定是拥有synchronized方法本身的这个对象)class Foo{}class MyHandler implements Runnable{
        Foo foo = new Foo();
        int i = 0;
        public  void run() {  
            synchronized(foo){ // 需要获得foo这个实例的锁,才能进入synchronized块,执行i++这个操作
                i++;
            }
            System.out.println(i);
        }
    }
    3. 使用java concurrent api,加锁更好(高大上)class MyHandler{
        private static Lock lock = new ReentrantLock();
        private int i = 0;
        
        public void hello(){
            lock.lock();  // 加锁,不再使用笨拙的synchronized
            try{
                i++;
                System.out.println(i);
            } finally{
                lock.unlock();  // 释放锁
            }
        }
    }
      

  6.   

    synchronized public void run()  是对象锁,锁定的是当前实例(this)楼主的想锁定Class ,可以把synchronized 加在静态方法上,这样就是楼主想要的结果了另外。
    楼主没发现自己这句话:第一个线程执行的时候锁定了m1,第二个线程应该拿不到m2的锁了吧. 
    已经语无伦次了么
    锁定了m1,是肯定拿不到m1的啊