当前位置:网站首页>线程API
线程API
2022-08-09 07:08:00 【lonesomee】
sleep阻塞
线程提供了一个静态方法:
- static void sleep(long ms)
- 使运行该方法的线程进入阻塞状态指定的毫秒,超时后线程会自动回到RUNNABLE状态等待再次获取时间片并发运行.
public class SleepDemo {
public static void main(String[] args) {
System.out.println("程序开始了!");
try {
Thread.sleep(5000);//主线程阻塞5秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("程序结束了!");
}
}
sleep方法处理异常:InterruptedException.
当一个线程调用sleep方法处于睡眠阻塞的过程中,该线程的interrupt()方法被调用时,sleep方法会抛出该异常从而打断睡眠阻塞.
守护线程与普通线程的区别:守护线程是通过普通线程调用setDaemon(true)设置而来的
主要区别体现在当java进程中所有的普通线程都结束时进程会结束,在结束前会杀死所有还在运行的守护线程。
public class DaemonThreadDemo {
public static void main(String[] args) {
Thread demo1 = new Thread(){
public void run(){
for(int i=0;i<5;i++){
System.out.println("222");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
System.out.println("111");
}
};
Thread demo2 = new Thread(){
public void run(){
while(true){
System.out.println("333");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
};
demo1.start();
demo2.setDaemon(true);//设置守护线程必须在线程启动前进行
demo2.start();
}
}
重点:多线程并发安全问题
- 什么是多线程并发安全问题:
当多个线程并发操作同一临界资源,由于线程切换时机不确定,导致执行顺序出现混乱。
解决办法:
将并发操作改为同步操作就可有效的解决多线程并发安全问题 - 同步与异步的概念:同步和异步都是说的多线程的执行方式。
多线程各自执行各自的就是异步执行,而多线程执行出现了先后顺序进行就是同步执行 public class SyncDemo { public static void main(String[] args) { Table table = new Table(); Thread t1 = new Thread(){ public void run(){ while(true){ int bean = table.getBean(); Thread.yield(); System.out.println(getName()+":"+bean); } } }; Thread t2 = new Thread(){ public void run(){ while(true){ int bean = table.getBean(); /* static void yield() 线程提供的这个静态方法作用是让执行该方法的线程 主动放弃本次时间片。 这里使用它的目的是模拟执行到这里CPU没有时间了,发生 线程切换,来看并发安全问题的产生。 */ Thread.yield(); System.out.println(getName()+":"+bean); } } }; t1.start(); t2.start(); } } class Table{ private int beans = 20;//桌子上有20个豆子 public int getBean(){ if(beans==0){ throw new RuntimeException("没有豆子了!"); } Thread.yield(); return beans--; } }
synchronized的两种用法
- 1.直接在方法上声明,此时该方法称为同步方法,同步方法同时只能被一个线程执行
2.同步块,推荐使用。同步块可以更准确的控制需要同步执行的代码片段。
有效的缩小同步范围可以在保证并发安全的前提下提高并发效率 public class SyncDemo { public static void main(String[] args) { Table table = new Table(); Thread t1 = new Thread(){ public void run(){ while(true){ int bean = table.getBean(); Thread.yield(); System.out.println(getName()+":"+bean); } } }; Thread t2 = new Thread(){ public void run(){ while(true){ int bean = table.getBean(); /* static void yield() 线程提供的这个静态方法作用是让执行该方法的线程 主动放弃本次时间片。 这里使用它的目的是模拟执行到这里CPU没有时间了,发生 线程切换,来看并发安全问题的产生。 */ Thread.yield(); System.out.println(getName()+":"+bean); } } }; t1.start(); t2.start(); } } class Table{ private int beans = 20;//桌子上有20个豆子 /** * 当一个方法使用synchronized修饰后,这个方法称为同步方法,多个线程不能 * 同时执行该方法。 * 将多个线程并发操作临界资源的过程改为同步操作就可以有效的解决多线程并发 * 安全问题。 * 相当于让多个线程从原来的抢着操作改为排队操作。 */ public synchronized int getBean(){ if(beans==0){ throw new RuntimeException("没有豆子了!"); } Thread.yield(); return beans--; } }
- 同步监视器对象的选取:
对于同步的成员方法而言,同步监视器对象不可指定,只能是this
对于同步的静态方法而言,同步监视器对象也不可指定,只能是类对象
对于同步块而言,需要自行指定同步监视器对象,选取原则:
1.必须是引用类型
2.多个需要同步执行该同步块的线程看到的该对象必须是同一个 - 互斥性
当使用多个synchronized修饰了多个代码片段,并且指定的同步监视器都是同一个对象时,这些代码片段就是互斥的,多个线程不能同时在这些代码片段上执行。
public class SyncDemo4 {
public static void main(String[] args) {
Foo foo = new Foo();
Thread t1 = new Thread(){
public void run(){
foo.methodA();
}
};
Thread t2 = new Thread(){
public void run(){
foo.methodB();
}
};
t1.start();
t2.start();
}
}
class Foo{
public synchronized void methodA(){
Thread t = Thread.currentThread();
try {
System.out.println(t.getName()+":正在执行A方法...");
Thread.sleep(5000);
System.out.println(t.getName()+":执行A方法完毕!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void methodB(){
Thread t = Thread.currentThread();
try {
System.out.println(t.getName()+":正在执行B方法...");
Thread.sleep(5000);
System.out.println(t.getName()+":执行B方法完毕!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
边栏推荐
猜你喜欢
细谈VR全景:数字营销时代的宠儿
DSP+ARM+FPGA高速PCIE/千兆网口信号仿真介绍
Built-in macros in C language (define log macros)
The Integer thread safe
分布式事务产生的原因
The working principle of the transformer (illustration, schematic explanation, understand at a glance)
Leetcode 70 stairs issues (Fibonacci number)
金九银十即将到来,求职套路多,面试指南我来分享~
更改Jupyter Notebook默认打开目录
【模板】树链剖分 P3384
随机推荐
2019南昌网络赛 C题,Hello 2019
XxlJobConfig distributed timer task management XxlJob configuration class, replace
AD picture PCB tutorial 20 minutes clear label shop operation process, copper network
HDU - 3183 A Magic Lamp Segment Tree
常用测试用例设计方法之正交实验法详解
分布式理论
Lottie系列三 :原理分析
MongDb query method
2022年7月小结
SIGINT, SIGKILL, SIGTERM signal difference, summary of various signals
SAP ALV data export many of the bugs
差分约束-图论
P1505 [国家集训队]旅游 树链剖分
线程池总结
灵活好用的sql monitoring 脚本 part7
Codeforces Round #359 (Div. 2) C. Robbers' watch Violent Enumeration
排序第二节——选择排序(选择排序+堆排序)(两个视频讲解)
Altium designer software commonly used the most complete package library, including schematic library, PCB library and 3D model library
Lottie系列二:高级属性
TCP段重组PDU