16-Java多线程开发

调用Thread类的Start方法

能够让线程启动
调用Start方法将线程从“就绪”0》“运行”

yield方法

能够让线程从“运行”-》“就绪”
原理:调用yield方法的线程,将自己的cpu时间片运行权限交给优先级同级或更高优先级线程持有运行。
使用:
1.有时间片轮询:yield方法不一定有效果,因为cpu轮换的速度很快
2.无时间片轮询:yield就会有用

线程优先级设置方法

Thread类的setPriority方法设置优先级。
优先级:1~10 1:最低 10:最高 默认:5
Thread类提供了一些简单的设置常量值:MIN_PRIORITY、NORM_PRIORITY、MAX_PRIORITY
注意:当无时间片轮询时,优先级才会出现作用

join - 线程插队

方法:
join(): 线程必须等待调用join方法的线程死亡才能继续运行,被插队的线程进入阻塞状态
join(long m):等待m个毫秒数后,调用join方法的线程如果还没死亡则停止插队,被插队的线程恢复就绪状态
join(long m,int nm):支持毫秒和纳秒的设置

join方法

public class MyThread2 implements Runnable{
    
    

    @Override
    public void run() {
    
    
        for (int i=1;i<=10;i++){
    
    
            if(Thread.currentThread().getName().equals("A")&& i==5){
    
    
                MyThread2 temp = new MyThread2();
                Thread tb  = new Thread(temp);
                tb.setName("B");
                tb.start();
                try {
    
    
                    tb.join();
                } catch (InterruptedException e) {
    
    
                    System.err.println("线程B启动异常");
                }
            }
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

sleep方法-线程睡眠

Thread.sleep(1000);// 在代码处使用一个新线程,阻塞当前正在执行的线程1秒后恢复运行
Thread.currentThread().sleep(1000);// 让当前正在运行的线程阻塞,1秒后恢复运行

synchronized

同步锁(非公平锁)
作用: 能让多个线程同步访问资源,实现线程安全操作

用法:

(1)方法上修饰
1. 非静态方法上修饰:锁是不是同一个对象(是不是同一个资源),就看调用方法的对象是否是同一个
2. 静态方法上修饰:锁定的是类,哪怕是不同对象,只要是属于同一个类,就能实现同步
(2)代码块上修饰
1. 对象锁:this或引用数据类型,看代码块参数中的对象是否是同一个
2. 类锁:通过定义的类的字节码文件对象值控制是否是同一个锁资源

以下内容测试代码

public static void main(String[] args) throws FileNotFoundException {
    
    

        CxkClass c1 = new CxkClass();//尝试使用同一对象和不同对象切换被多个线程调用
        CxkClass c2 = new CxkClass();

        //匿名类
        new Thread(()->{
    
    
            c1.fun1();
        },"A").start();

        //匿名类
        new Thread(()->{
    
    
            c1.fun1();
        },"B").start();

    }

synchronized-方法上修饰-非静态

public class CxkClass {
    
    

    public synchronized void fun1() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + "--" + "fun1:=>" + i);
        }
    }

    public synchronized void fun2() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            System.out.println("fun2:=>" + i);
        }
    }

}

synchronized-方法上修饰-静态

public static synchronized void fun1() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + "--" + "fun1:=>" + i);
        }
    }

    public static synchronized void fun2() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            System.out.println("fun2:=>" + i);
        }
    }

synchronized-代码块-对象锁

public class CxkClass {
    
    

    private final static Object key = new Object();
    
    public  void fun1(){
    
    
        
        synchronized (key){
    
    // 对象锁
            for(int i=0;i<10;i++){
    
    
                System.out.println(Thread.currentThread().getName()+"--"+"fun1:=>"+i);
            }
        }
    }

    public  void fun2(){
    
    

        synchronized (key) {
    
    // 对象锁
            for (int i = 0; i < 10; i++) {
    
    
                System.out.println("fun2:=>" + i);
            }
        }
    }

}

synchronized-代码块-类锁

public class CxkClass {
    
    

    public  void fun1(){
    
    

        synchronized (this.getClass()){
    
    // 类锁
            for(int i=0;i<10;i++){
    
    
                System.out.println(Thread.currentThread().getName()+"--"+"fun1:=>"+i);
            }
        }
    }

    public  void fun2(){
    
    

        synchronized (this.getClass()) {
    
    // 类锁
            for (int i = 0; i < 10; i++) {
    
    
                System.out.println("fun2:=>" + i);
            }
        }
    }

}

匿名线程类

//匿名类
        new Thread(){
    
    

            @Override
            public void run() {
    
    
                super.run();
            }
        }.start();
        
        
        
        new Thread(()->{
    
    
            
        },"A").start();

线程通信

wait() - 释放当前锁的资源(释放锁就会进入阻塞)

调用wait的是:锁对象,不是线程对象

notify() notifyAll() - 唤醒一个或所有当前锁中阻塞的线程

notify: 只会唤醒其中一个(随机)
(1)无时间片轮询:notify唤醒的是同级别或更高优先级的线程
notifyAll:唤醒所有阻塞线程,全部唤醒(比较安全)

public static void main(String[] args) throws FileNotFoundException {
    
    

        CxkClass c1 = new CxkClass();
        //CxkClass c2 = new CxkClass();

        //匿名类
        new Thread(()->{
    
    
            try {
    
    
                c1.fun1();
            } catch (InterruptedException e) {
    
    
                System.err.println("线程异常");
            }
        },"A").start();


        new Thread(()->{
    
    
            try {
    
    
                c1.fun1();
            } catch (InterruptedException e) {
    
    
                System.err.println("线程异常");
            }
        },"A1").start();

        //匿名类
        new Thread(()->{
    
    
                c1.fun2();
        },"B").start();

    }



public class CxkClass {
    
    

    public synchronized void fun1() throws InterruptedException {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            if((Thread.currentThread().getName().equals("A")||
                    Thread.currentThread().getName().equals("A1"))&&
                            i==5){
    
    
                this.wait();// 当前线程进入等待状态
            }
            System.out.println(Thread.currentThread().getName() + "--" + "fun1:=>" + i);
        }
    }

    public synchronized void fun2() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            if(Thread.currentThread().getName().equals("B")&&i==5){
    
    
                this.notifyAll();// 唤醒当前在同一个类型锁中正在阻塞的线程
            }
            System.out.println(Thread.currentThread().getName() + "fun2:=>" + i);
        }
    }

}

重入锁

public class CxkClass {
    
    

    ReentrantLock lock = new ReentrantLock();//重入锁对象

    public  void fun1() throws InterruptedException {
    
    
        lock.lock();//锁定
        for (int i = 0; i < 10; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + "--" + "fun1:=>" + i);
        }
        lock.unlock();
    }

    public  void fun2() {
    
    
        lock.lock();//锁定
        for (int i = 0; i < 10; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + "fun2:=>" + i);
        }
        lock.unlock();
    }

}

多线程中集合线程安全问题

Collections.synchronized集合类型方法

List<String> list = new ArrayList<>();
        Set<String> set = new HashSet<>();
        Map<String,Object> map = new HashMap<>();

        //返回一个线程安全的集合
        List<String> newList = Collections.synchronizedList(list);
        Set<String> strings = Collections.synchronizedSet(set);
        Map<String, Object> stringObjectMap = Collections.synchronizedMap(map);

猜你喜欢

转载自blog.csdn.net/gjb760662328/article/details/129164356