中华住房与城乡建设厅网站网站系统建设项目
- 作者: 五速梦信息网
- 时间: 2026年04月20日 03:48
当前位置: 首页 > news >正文
中华住房与城乡建设厅网站,网站系统建设项目,怎么免费建自己的网站,做h5网站公司《编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程》一文详细讲述了线程、进程的关系及在操作系统中的表现#xff0c;这是多线程学习必须了解的基础。本文将接着讲一下Java线程同步中的一个重要的概念synchronized. synchronized是Java中的关键字#xff0c… 《编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程》一文详细讲述了线程、进程的关系及在操作系统中的表现这是多线程学习必须了解的基础。本文将接着讲一下Java线程同步中的一个重要的概念synchronized. synchronized是Java中的关键字是一种同步锁。它修饰的对象有以下几种 修饰一个代码块被修饰的代码块称为同步语句块其作用的范围是大括号{}括起来的代码作用的对象是调用这个代码块的对象修饰一个方法被修饰的方法称为同步方法其作用的范围是整个方法作用的对象是调用这个方法的对象修改一个静态的方法其作用的范围是整个静态方法作用的对象是这个类的所有对象修改一个类其作用的范围是synchronized后面括号括起来的部分作用主的对象是这个类的所有对象。 修饰一个代码块 一个线程访问一个对象中的synchronized(this)同步代码块时其他试图访问该对象的线程将被阻塞。我们看下面一个例子 【Demo1】synchronized的用法 /*** 同步线程*/ class SyncThread implements Runnable {private static int count;public SyncThread() {count 0;}public void run() {synchronized(this) {for (int i 0; i 5; i) {try {System.out.println(Thread.currentThread().getName() : (count));Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}public int getCount() {return count;} }SyncThread的调用 SyncThread syncThread new SyncThread(); Thread thread1 new Thread(syncThread, SyncThread1); Thread thread2 new Thread(syncThread, SyncThread2); thread1.start(); thread2.start();结果如下 SyncThread1:0 SyncThread1:1 SyncThread1:2 SyncThread1:3 SyncThread1:4 SyncThread2:5 SyncThread2:6 SyncThread2:7 SyncThread2:8 SyncThread2:9当两个并发线程(thread1和thread2)访问同一个对象(syncThread)中的synchronized代码块时在同一时刻只能有一个线程得到执行另一个线程受阻塞必须等待当前线程执行完这个代码块以后才能执行该代码块。Thread1和thread2是互斥的因为在执行synchronized代码块时会锁定当前的对象只有执行完该代码块才能释放该对象锁下一个线程才能执行并锁定该对象。 我们再把SyncThread的调用稍微改一下 Thread thread1 new Thread(new SyncThread(), SyncThread1); Thread thread2 new Thread(new SyncThread(), SyncThread2); thread1.start(); thread2.start();结果如下 SyncThread1:0 SyncThread2:1 SyncThread1:2 SyncThread2:3 SyncThread1:4 SyncThread2:5 SyncThread2:6 SyncThread1:7 SyncThread1:8 SyncThread2:9不是说一个线程执行synchronized代码块时其它的线程受阻塞吗为什么上面的例子中thread1和thread2同时在执行。这是因为synchronized只锁定对象每个对象只有一个锁lock与之相关联而上面的代码等同于下面这段代码 SyncThread syncThread1 new SyncThread(); SyncThread syncThread2 new SyncThread(); Thread thread1 new Thread(syncThread1, SyncThread1); Thread thread2 new Thread(syncThread2, SyncThread2); thread1.start(); thread2.start();这时创建了两个SyncThread的对象syncThread1和syncThread2线程thread1执行的是syncThread1对象中的synchronized代码(run)而线程thread2执行的是syncThread2对象中的synchronized代码(run)我们知道synchronized锁定的是对象这时会有两把锁分别锁定syncThread1对象和syncThread2对象而这两把锁是互不干扰的不形成互斥所以两个线程可以同时执行。 2.当一个线程访问对象的一个synchronized(this)同步代码块时另一个线程仍然可以访问该对象中的非synchronized(this)同步代码块。 【Demo2】多个线程访问synchronized和非synchronized代码块 class Counter implements Runnable{private int count;public Counter() {count 0;}public void countAdd() {synchronized(this) {for (int i 0; i 5; i ) {try {System.out.println(Thread.currentThread().getName() : (count));Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}//非synchronized代码块未对count进行读写操作所以可以不用synchronizedpublic void printCount() {for (int i 0; i 5; i ) {try {System.out.println(Thread.currentThread().getName() count: count);Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}public void run() {String threadName Thread.currentThread().getName();if (threadName.equals(A)) {countAdd();} else if (threadName.equals(B)) {printCount();}} }调用代码: Counter counter new Counter(); Thread thread1 new Thread(counter, A); Thread thread2 new Thread(counter, B); thread1.start(); thread2.start();结果如下 A:0 B count:1 A:1 B count:2 A:2 B count:3 A:3 B count:4 A:4 B count:5上面代码中countAdd是一个synchronized的printCount是非synchronized的。从上面的结果中可以看出一个线程访问一个对象的synchronized代码块时别的线程可以访问该对象的非synchronized代码块而不受阻塞。 指定要给某个对象加锁 【Demo3】:指定要给某个对象加锁 /** 银行账户类/ class Account {String name;float amount;public Account(String name, float amount) {this.name name;this.amount amount;}//存钱public void deposit(float amt) {amount amt;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}//取钱public void withdraw(float amt) {amount - amt;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}public float getBalance() {return amount;} } /** 账户操作类*/ class AccountOperator implements Runnable{private Account account;public AccountOperator(Account account) {this.account account;}public void run() {synchronized (account) {account.deposit(500);account.withdraw(500);System.out.println(Thread.currentThread().getName() : account.getBalance());}} }调用代码: Account account new Account(zhang san, 10000.0f); AccountOperator accountOperator new AccountOperator(account); final int THREAD_NUM 5; Thread threads[] new Thread[THREAD_NUM]; for (int i 0; i THREAD_NUM; i ) {threads[i] new Thread(accountOperator, Thread i);threads[i].start(); }结果如下 Thread3:10000.0 Thread2:10000.0 Thread1:10000.0 Thread4:10000.0 Thread0:10000.0在AccountOperator 类中的run方法里我们用synchronized 给account对象加了锁。这时当一个线程访问account对象时其他试图访问account对象的线程将会阻塞直到该线程访问account对象结束。也就是说谁拿到那个锁谁就可以运行它所控制的那段代码。 当有一个明确的对象作为锁时就可以用类似下面这样的方式写程序。 public void method3(SomeObject obj) {//obj 锁定的对象synchronized(obj){// todo} }当没有明确的对象作为锁只是想让一段代码同步时可以创建一个特殊的对象来充当锁 c lass Test implements Runnable {private byte[] lock new byte[0]; // 特殊的instance变量public void method(){synchronized(lock) {// todo 同步代码块}}public void run() {} }说明零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码生成零长度的byte[]对象只需3条操作码而Object lock new Object()则需要7行操作码。 修饰一个方法 Synchronized修饰一个方法很简单就是在方法的前面加synchronizedpublic synchronized void method(){//todo}; synchronized修饰方法和修饰一个代码块类似只是作用范围不一样修饰代码块是大括号括起来的范围而修饰方法范围是整个函数。如将【Demo1】中的run方法改成如下的方式实现的效果一样。 【Demo4】synchronized修饰一个方法 public synchronized void run() {for (int i 0; i 5; i ) {try {System.out.println(Thread.currentThread().getName() : (count));Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}} }Synchronized作用于整个方法的写法。 写法一 public synchronized void method() {// todo }写法二 public void method() {synchronized(this) {// todo} }写法一修饰的是一个方法写法二修饰的是一个代码块但写法一与写法二是等价的都是锁定了整个方法时的内容。 在用synchronized修饰方法时要注意以下几点 synchronized关键字不能继承。 虽然可以使用synchronized来定义方法但synchronized并不属于方法定义的一部分因此synchronized关键字不能被继承。如果在父类中的某个方法使用了synchronized关键字而在子类中覆盖了这个方法在子类中的这个方法默认情况下并不是同步的而必须显式地在子类的这个方法中加上synchronized关键字才可以。当然还可以在子类方法中调用父类中相应的方法这样虽然子类中的方法不是同步的但子类调用了父类的同步方法因此子类的方法也就相当于同步了。这两种方式的例子代码如下 在子类方法中加上synchronized关键字 class Parent {public synchronized void method() { } } class Child extends Parent {public synchronized void method() { } }在子类方法中调用父类的同步方法 class Parent {public synchronized void method() { } } class Child extends Parent {public void method() { super.method(); } }在定义接口方法时不能使用synchronized关键字。 构造方法不能使用synchronized关键字但可以使用synchronized代码块来进行同步。 修饰一个静态的方法 Synchronized也可修饰一个静态方法用法如下 public synchronized static void method() {// todo }我们知道静态方法是属于类的而不属于对象的。同样的synchronized修饰的静态方法锁定的是这个类的所有对象。我们对Demo1进行一些修改如下 【Demo5】synchronized修饰静态方法 /** 同步线程/ class SyncThread implements Runnable {private static int count;public SyncThread() {count 0;}public synchronized static void method() {for (int i 0; i 5; i ) {try {System.out.println(Thread.currentThread().getName() : (count));Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}public synchronized void run() {method();} }调用代码: SyncThread syncThread1 new SyncThread(); SyncThread syncThread2 new SyncThread(); Thread thread1 new Thread(syncThread1, SyncThread1); Thread thread2 new Thread(syncThread2, SyncThread2); thread1.start(); thread2.start();结果如下 SyncThread1:0 SyncThread1:1 SyncThread1:2 SyncThread1:3 SyncThread1:4 SyncThread2:5 SyncThread2:6 SyncThread2:7 SyncThread2:8 SyncThread2:9syncThread1和syncThread2是SyncThread的两个对象但在thread1和thread2并发执行时却保持了线程同步。这是因为run中调用了静态方法method而静态方法是属于类的所以syncThread1和syncThread2相当于用了同一把锁。这与Demo1是不同的。 修饰一个类 Synchronized还可作用于一个类用法如下 class ClassName {public void method() {synchronized(ClassName.class) {// todo}} }我们把Demo5再作一些修改。 【Demo6】:修饰一个类 /** 同步线程*/ class SyncThread implements Runnable {private static int count;public SyncThread() {count 0;}public static void method() {synchronized(SyncThread.class) {for (int i 0; i 5; i ) {try {System.out.println(Thread.currentThread().getName() : (count));Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}public synchronized void run() {method();} }其效果和【Demo5】是一样的synchronized作用于一个类T时是给这个类T加锁T的所有对象用的是同一把锁。
相关文章
-
中华智能自建代理网站网站开发技术考试试卷
中华智能自建代理网站网站开发技术考试试卷
- 技术栈
- 2026年04月20日
-
中恒诚信建设有限公司网站株洲网站建设工作室
中恒诚信建设有限公司网站株洲网站建设工作室
- 技术栈
- 2026年04月20日
-
中核工建设集团网站大气家具营销型网站源码
中核工建设集团网站大气家具营销型网站源码
- 技术栈
- 2026年04月20日
-
中化山东公路建设集团网站wordpress侧栏菜单加上序号
中化山东公路建设集团网站wordpress侧栏菜单加上序号
- 技术栈
- 2026年04月20日
-
中徽园林建设有限公司网站torrentkitty磁力搜索引擎
中徽园林建设有限公司网站torrentkitty磁力搜索引擎
- 技术栈
- 2026年04月20日
-
中济建设官方网站建站公司哪家好
中济建设官方网站建站公司哪家好
- 技术栈
- 2026年04月20日
