Java修炼——线程同步的俩种方法
2024-09-01 19:01:42
当多线程去同时抢占CPU资源时,有多线程的安全问题。这时候就需要将线程同步。线程同步有俩个方法。
1.同步代码块(synchronize),同步代码块需要同步监视器,同步监视器是针对对象进行操作。什么对象时共享的,就可以给他加上同步监视器。
package com.bjsxt.ticker;
public class Ticket implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
synchronized (this) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
}
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.bjsxt.ticker;
public class TestTicket01 {
public static void main(String[] args) {
Ticket t=new Ticket();
Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
打印输出结果:
2.第二种就是同步方法:
package com.bjsxt.ticker;
public class Ticket1 implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
this.saleTicket();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private synchronized void saleTicket() {//同步方法不需要指定同步监视器,同步监视器只能是当前对象this
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
}
}
package com.bjsxt.ticker;
public class TestTicket01 {
public static void main(String[] args) {
Ticket1 t=new Ticket1();
Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
运行结果:
进行对比,我们将没有用线程同步的程序拿过来看看:
package com.bjsxt.ticker;
public class Ticket2 implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
if (ticket > 0) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
}
}
}
package com.bjsxt.ticker;
public class TestTicket01 {
public static void main(String[] args) {
Ticket2 t=new Ticket2();
Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
运行结果:
可以看到,没有用同步方法,连0和-1都出来了,甚至还有俩个窗口卖同一张票的。这就是多线程没有用同步方法的线程安全。
最新文章
- 【.net 深呼吸】自定义缓存配置(非Web项目)
- 利用CSOM向列表添加文件夹
- Jquery对文本框的值、字符串的验证;正则表达式字符串的验证
- Script Form
- Python之路第八天,基础(9)-面向对象(下)
- oracle form 触发器执行顺序及键定义[Z]
- 使用命令创建github代码仓库,push本地仓库到github远程代码仓库
- Linux端图形处理工具ImageMagick在Centos上的安装
- IDEA 下新建 Hibernate 项目
- shell 批量修改较长字符串 字符串内容之间更换位置
- 数据库database
- java保留字
- Git分支merge和rebase的区别
- OpenCV图像分割2
- .net里Release的pdb文件有什么用 是否可以删除
- 使用bat文件执行sql文件
- 3. group_concat与oracle中wm_concat用法一样
- 弹性盒子 flexbox 元素居中
- ssh框架配置数据源 数据库连接没有正常释放
- ECCV 2014 Results (16 Jun, 2014) 结果已出