美文网首页
java多线程基础学习(四)

java多线程基础学习(四)

作者: ccq_inori | 来源:发表于2018-04-22 21:00 被阅读0次

    上一次接触了关键字synchronized,虽然能够使线程同步且不出现脏读的情况,但是它在某些情况下还是有弊端的,如果A线程调用同步方法执行一个长时间的任务,那么B线程则必须等待比较长的时间。这样子就是造成程序执行效率低下。那么该如何使用关键字synchronized呢。在synchronized块中就是同步执行,不在的话就是异步执行。没错,那么我们把它弄成一半异步,一半同步,这样子既能提高程序执行效率又能不出现脏读。

    public class Task 
    {
        public void dolongTimeTask()
        {
            for(int i=0;i<100;i++)
            {
                System.out.println("nosynchronized threadName="+Thread.currentThread().getName()+" i="+(i+1));
            }
            System.out.println("");
            synchronized (this)
            {
                for(int i=0;i<100;i++)
                {
                    System.out.println("synchronized threadName="+Thread.currentThread().getName()+" i="+(i+1));
                }
            }
        }
    }
    
        public static void main(String[] args) 
        {
            Task t=new Task();
            ThreadA ta=new ThreadA(t);
            ta.start();
            ThreadB tb=new ThreadB(t);
            tb.start();
        }
    
    在使用同步synchronized(this)代码块时需要注意,当一个线程访问object的一个synchronized (this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将会被阻塞,这说明synchronized 使用的“对象监视器”是一个。
    多个线程调用同一个对象中的不同名称的synchronized 同步方法或者synchronized(this)代码块时,调用的效果就是按顺序执行,也就是同步的,阻塞的。

    (1)synchronized同步方法
    1)对其他synchronized 同步方法或synchronized (this)同步块调用呈阻塞作用
    2)同一时间只有一个线程可以执行synchronized同步方法中的代码
    (1)synchronized(this)同步代码块
    1)对其他synchronized 同步方法或synchronized (this)同步块调用呈阻塞作用
    2)同一时间只有一个线程可以执行synchronized(this)同步方法中的代码

    还有一点,如果对象监视器不是同一个的话那么结果就是异步调用了,就会交叉运行。

    public class Service 
    {
        public void Test()
        {
            try
            {
                String anything=new String();
                synchronized (anything) 
                {
                    System.out.println("线程的名称:"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"进入同步块");
                    Thread.sleep(3000);
                    System.out.println("线程的名称:"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"离开同步块");
                }
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    public class Run {
    
        public static void main(String[] args) 
        {
            Service s=new Service();
            ThreadA ta=new ThreadA(s);
            ta.setName("A");
            ta.start();
            ThreadB tb=new ThreadB(s);
            tb.setName("B");
            tb.start();
        }
    
    }
    

    synchronized(非this对象x)格式的写法是将x对象本身作为"对象监视器",这样子可以得出:

    1.当多个线程同时执行synchronized(x){}同步代码块时呈同步效果

    2.当其他线程执行x对象中的synchronized同步方法呈同步效果

    3.当其他线程执行x对象里面的synchronized(this)代码块时也呈同步效果。

    这里举出第二个结论的例子:
    public class MyObject 
    {
        synchronized public void testMyObjectMethod()
        {
            System.out.println("testMyObjectMethod getlock time="+System.currentTimeMillis()+"run threadName="+Thread.currentThread().getName());
            System.out.println("---------------");
            System.out.println("testMyObjectMethod releaselock time="+System.currentTimeMillis()+"run threadName="+Thread.currentThread().getName());
        }
    }
    
        public void testMethod1(MyObject myobject) 
        {
            synchronized (myobject) 
            {
                try
                {
                    System.out.println("testMethod1   getlock time="+System.currentTimeMillis()+"run threadName="+Thread.currentThread().getName());
                    Thread.sleep(5000);
                    System.out.println("testMethod1   releaseLock time="+System.currentTimeMillis()+"run threadName="+Thread.currentThread().getName());
                    
                }
                catch(InterruptedException e)
                {
                    
                }
            }
        }
    
    public class ThreadA extends Thread 
    {
        private Service s;
        private MyObject m;
        public ThreadA(Service s,MyObject m)
        {
            this.s=s;
            this.m=m;
        }
        public void run()
        {
            s.testMethod1(m);
        }
    }
    
    public class ThreadB extends Thread 
    {
        private MyObject m;
        public ThreadB(MyObject m)
        {
            this.m=m;
        }
        public void run()
        {
            m.testMyObjectMethod();
        }
    }
    
    public class Run {
    
        public static void main(String[] args) 
        {
            Service s=new Service();
            MyObject m=new MyObject();
            ThreadA ta=new ThreadA(s,m);
            ta.setName("a");
            ta.start();
            ThreadB tb=new ThreadB(m);
            tb.setName("b");
            tb.start();
    
        }
    
    }
    
    前面的三个结论,一和三都好理解,因为前面一直接触着synchronized关键字。那么只有第二个结论,前面也也没有类似的例子,所以有点理解不了,所以单独拿出来,也是再次理清自己学习多线程的思路。

    相关文章

      网友评论

          本文标题:java多线程基础学习(四)

          本文链接:https://www.haomeiwen.com/subject/udmfkftx.html