线程的优先级
- 线程的优先级有1-10十级,数值越高优先级越高(超出范围会抛出异常)
- getPriority()和setPriority(int)分别用来获取和设置线程的优先级
- 优先级高只是增加对应线程被cpu调度执行的概率,并不代表该线程会一直比优先级低的线程先执行
- **注意:**线程设置优先级建议在线程启动之前
public class Test1 implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"---->"+Thread.currentThread().getPriority());
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getPriority());
Test1 t=new Test1();
Thread t1=new Thread(t,"1");
Thread t2=new Thread(t,"2");
Thread t3=new Thread(t,"3");
Thread t4=new Thread(t,"4");
Thread t5=new Thread(t,"5");
Thread t6=new Thread(t,"6");
//设置优先级
t1.setPriority(1);
t2.setPriority(3);
t4.setPriority(6);
t5.setPriority(8);
t6.setPriority(10);
//启动线程
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}
守护线程
- 线程分为用户线程和守护线程
- java虚拟机必须确保用户线程执行完毕而不用等待守护线程
- 守护线程作用:记录日志、监控内存、垃圾回收等等
- setDaemon(true)方法把线程设置为守护线程
public class Test2 {
public static void main(String[] args) {
De de=new De();
User user=new User();
//守护线程
Thread thread=new Thread(de);
//把线程设置为守护线程
thread.setDaemon(true);
thread.start();
//用户线程
new Thread(user).start();
}
}
//守护线程
class De implements Runnable{
@Override
public void run() {
while (true){
System.out.println("defender running");
}
}
}
//用户线程
class User implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("User running");
}
}
}
可以看到,即使守护线程写成while true死循环,也会在用户线程执行完毕后自动退出
线程同步
- 使用多线程时,若多个线程访问同一个对象,尤其是对对象进行修改操作时,就需要引入线程同步。多个线程需要访问同一对象时,进入该线程的等待池,只有当前面线程访问结束,后面的线程才能够访问到该对象。
- 主要引入锁和队列的概念:队列即排队,线程访问对象应该有先后顺序;锁即在线程访问对象在对对象进行操作之前,给对象上锁即可防止其他线程对对象进行访问操作。
- 同步方法
- 使用synchronized关键字对代码块或者方法进行修饰,即可控制对每一个对象的访问,每一个对象都对应一把锁,只有获得锁的方法可以对对象进行访问操作,没有获得锁的线程将会被阻塞,等待直到占用锁的线程施放锁。
- 注意:使用synchronized声明一个大的代码块将会影响代码的执行效率。
- 多个线程对多个对象同时操作时,有可能会造成死锁的情况
- 可以使用synchronized关键字直接修饰方法,此时默认锁的对象为“this”
- 也可以使用synchronized(Object obj){代码块} 的形式,其中obj为被锁的对象。
死锁测试:
public class Test4 {
public static void main(String[] args) {
Lock lock= new Lock();
new Thread(lock,"1").start();
new Thread(lock,"2").start();
}
}
class Lock implements Runnable{
//两个被访问的对象
private int num1=1,num2=2;
//synchronized void lock(int num){
void lock(int num){
System.out.println("线程"+Thread.currentThread().getName()+"成功锁num"+num);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("1")){
//如果是线程1 先锁1再锁2
System.out.println("线程"+Thread.currentThread().getName()+"尝试锁num1");
synchronized ((Object) num1){
lock(num1);
System.out.println("线程"+Thread.currentThread().getName()+"尝试锁num2");
synchronized ((Object) num2){
lock(num2);
}
}
}else{
//如果是线程2,先锁2再锁1
System.out.println("线程"+Thread.currentThread().getName()+"尝试锁num2");
synchronized ((Object) num2){
lock(num2);
System.out.println("线程"+Thread.currentThread().getName()+"尝试锁num1");
synchronized ((Object) num1){
lock(num1);
}
}
}
}
}
- 可以看到出现了死锁现象
转载:https://blog.csdn.net/qq_38425976/article/details/106389159
查看评论