千家信息网

Java多线程synchronized关键字怎么输出

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍"Java多线程synchronized关键字怎么输出",在日常操作中,相信很多人在Java多线程synchronized关键字怎么输出问题上存在疑惑,小编查阅了各式资料,整理出简单好
千家信息网最后更新 2026年11月01日Java多线程synchronized关键字怎么输出

这篇文章主要介绍"Java多线程synchronized关键字怎么输出",在日常操作中,相信很多人在Java多线程synchronized关键字怎么输出问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java多线程synchronized关键字怎么输出"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1,是否使用synchronized关键字的不同

public class ThreadTest {     public static void main(String[] args)     {         Example example = new Example();          Thread t1 = new Thread1(example);         Thread t2 = new Thread1(example);          t1.start();         t2.start();     }  }  class Example {     public synchronized void execute()     {         for (int i = 0; i < 10; ++i)         {             try             {                 Thread.sleep(500);             }             catch (InterruptedException e)             {                 e.printStackTrace();             }             System.out.println("Hello: " + i);         }     }  }  class Thread1 extends Thread {     private Example example;      public Thread1(Example example)     {         this.example = example;     }      @Override     public void run()     {         example.execute();     }  }

是否在execute()方法前加上synchronized关键字,这个例子程序的执行结果会有很大的不同。

如果不加synchronized关键字,则两个线程同时执行execute()方法,输出是两组并发的。

如果加上synchronized关键字,则会先输出一组0到9,然后再输出下一组,说明两个线程是顺次执行的。

2.多个方法的多线程情况

将程序改动一下,Example类中再加入一个方法execute2()。

之后再写一个线程类Thread2,Thread2中的run()方法执行的是execute2()。Example类中的两个方法都是被synchronized关键字修饰的。

public class ThreadTest {     public static void main(String[] args)     {         Example example = new Example();          Thread t1 = new Thread1(example);         Thread t2 = new Thread2(example);          t1.start();         t2.start();     }  }  class Example {     public synchronized void execute()     {         for (int i = 0; i < 20; ++i)         {             try             {                 Thread.sleep((long) Math.random() * 1000);             }             catch (InterruptedException e)             {                 e.printStackTrace();             }             System.out.println("Hello: " + i);         }     }      public synchronized void execute2()     {         for (int i = 0; i < 20; ++i)         {             try             {                 Thread.sleep((long) Math.random() * 1000);             }             catch (InterruptedException e)             {                 e.printStackTrace();             }             System.out.println("World: " + i);         }     }  }  class Thread1 extends Thread {     private Example example;      public Thread1(Example example)     {         this.example = example;     }      @Override     public void run()     {         example.execute();     }  }  class Thread2 extends Thread {     private Example example;      public Thread2(Example example)     {         this.example = example;     }      @Override     public void run()     {         example.execute2();     }  }

如果去掉synchronized关键字,则两个方法并发执行,并没有相互影响。

但是如例子程序中所写,即便是两个方法:

执行结果永远是执行完一个线程的输出再执行另一个线程的。

说明:

如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕前,其他线程是无法访问该对象的任何synchronized方法的。

结论:

当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。

Java中的每个对象都有一个锁(lock),或者叫做监视器(monitor),当一个线程访问某个对象的synchronized方法时,将该对象上锁,其他任何线程都无法再去访问该对象的synchronized方法了(这里是指所有的同步方法,而不仅仅是同一个方法),直到之前的那个线程执行方法完毕后(或者是抛出了异常),才将该对象的锁释放掉,其他线程才有可能再去访问该对象的synchronized方法。

注意这时候是给对象上锁,如果是不同的对象,则各个对象之间没有限制关系。

尝试在代码中构造第二个线程对象时传入一个新的Example对象,则两个线程的执行之间没有什么制约关系。

3.考虑静态的同步方法

当一个synchronized关键字修饰的方法同时又被static修饰,之前说过,非静态的同步方法会将对象上锁,但是静态方法不属于对象,而是属于类,它会将这个方法所在的类的Class对象上锁。

一个类不管生成多少个对象,它们所对应的是同一个Class对象。

public class ThreadTest {     public static void main(String[] args)     {         Example example = new Example();          Thread t1 = new Thread1(example);          // 此处即便传入不同的对象,静态方法同步仍然不允许多个线程同时执行         example = new Example();          Thread t2 = new Thread2(example);          t1.start();         t2.start();     }  }  class Example {     public synchronized static void execute()     {         for (int i = 0; i < 20; ++i)         {             try             {                 Thread.sleep((long) Math.random() * 1000);             }             catch (InterruptedException e)             {                 e.printStackTrace();             }             System.out.println("Hello: " + i);         }     }      public synchronized static void execute2()     {         for (int i = 0; i < 20; ++i)         {             try             {                 Thread.sleep((long) Math.random() * 1000);             }             catch (InterruptedException e)             {                 e.printStackTrace();             }             System.out.println("World: " + i);         }     }  }  class Thread1 extends Thread {     private Example example;      public Thread1(Example example)      {         this.example = example;     }      @Override     public void run()     {         Example.execute();     }  }  class Thread2 extends Thread {     private Example example;      public Thread2(Example example)     {         this.example = example;     }      @Override     public void run()     {         Example.execute2();     }  }

所以如果是静态方法的情况(execute()和execute2()都加上static关键字),即便是向两个线程传入不同的Example对象,这两个线程仍然是互相制约的,必须先执行完一个,再执行下一个。

结论:

如果某个synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在的类所对应的Class对象。Java中,无论一个类有多少个对象,这些对象会对应***一个Class对象,因此当线程分别访问同一个类的两个对象的两个static,synchronized方法时,它们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始。

4. synchronized块

synchronized块写法:

synchronized(object)

{

}

表示线程在执行的时候会将object对象上锁。(注意这个对象可以是任意类的对象,也可以使用this关键字)。

这样就可以自行规定上锁对象。

public class ThreadTest {     public static void main(String[] args)     {         Example example = new Example();          Thread t1 = new Thread1(example);         Thread t2 = new Thread2(example);          t1.start();         t2.start();     }  }  class Example {     private Object object = new Object();      public void execute()     {         synchronized (object)         {             for (int i = 0; i < 20; ++i)             {                 try                 {                     Thread.sleep((long) Math.random() * 1000);                 }                 catch (InterruptedException e)                 {                     e.printStackTrace();                 }                 System.out.println("Hello: " + i);             }          }      }      public void execute2()     {         synchronized (object)         {             for (int i = 0; i < 20; ++i)             {                 try                 {                     Thread.sleep((long) Math.random() * 1000);                 }                 catch (InterruptedException e)                 {                     e.printStackTrace();                 }                 System.out.println("World: " + i);             }          }      }  }  class Thread1 extends Thread {     private Example example;      public Thread1(Example example)     {         this.example = example;     }      @Override     public void run()     {         example.execute();     }  }  class Thread2 extends Thread {     private Example example;      public Thread2(Example example)     {         this.example = example;     }      @Override     public void run()     {         example.execute2();     }  }

例子程序4所达到的效果和例子程序2的效果一样,都是使得两个线程的执行顺序进行,而不是并发进行,当一个线程执行时,将object对象锁住,另一个线程就不能执行对应的块。

synchronized方法实际上等同于用一个synchronized块包住方法中的所有语句,然后在synchronized块的括号中传入this关键字。当然,如果是静态方法,需要锁定的则是class对象。

可能一个方法中只有几行代码会涉及到线程同步问题,所以synchronized块比synchronized方法更加细粒度地控制了多个线程的访问,只有synchronized块中的内容不能同时被多个线程所访问,方法中的其他语句仍然可以同时被多个线程所访问(包括synchronized块之前的和之后的)。

注意:被synchronized保护的数据应该是私有的。

到此,关于"Java多线程synchronized关键字怎么输出"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

方法 线程 对象 关键 关键字 两个 输出 多个 静态 同步 不同 同时 程序 学习 例子 所在 顺序 之间 代码 只有 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技开发公司 科技与互联网发展 科技创新互联网企业 易通互联网络科技有限公司 融贸通互联网科技 互联网科技公司招聘 安控科技rtu产品工业互联网 浙江互联网科技研学营 互联网与医疗科技 广州市恰铎互联网科技有限公司 呼和浩特新华互联网科技学院 互联网金融科技展 长沙茂晟互联网科技有限公司 中科明德北京互联网科技 科技互联网的核心竞争力 互联网时代科技型公司的机会 广州智享互联网科技 盐城市攀科互联网科技有限公司 北京品多多互联网科技有限公司 安徽九吞吴互联网科技有限公司 湖南永感互联网科技有限公司 麻工互联网科技 互联网与未来科技 迪茉互联网科技 互联网科技上市公司 彤创互联网科技有限公司 苏州五指互联网络科技有限 洛阳昕诺飞互联网科技有限公司 山东子淼互联网科技有限公司 浙南科技城互联网大厦招聘
0