记录学习每一天-day24

1.1 Thread 类

join

 join : 合并线程,多个线程合并为一个线程

public static void main(String[] args) {
        Thread t1=new Thread(new Processer_1());
        Thread t2=new Thread(new Processer_1());
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();
        try{
            //执行到join的时候,因为是t1调用的,所以main之后的代码,必须等t1执行完之后才能执行
            t1.join();
        }catch(Exception e){
            e.printStackTrace();
        }
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
            
        }
        
    }

 yield

 yield:暂停当前正在执行的线程,并让其他线程执行
 *         1,静态方法,写在哪个线程中,哪个线程让位
 *         2,给同优先级让位,不同优先级不让位
 *         3,只让出当前执行的时间片,下次让不让不知道
 *         
 * yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。
 * 因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。
 * 但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。
 *       结论:yield()从未导致线程转到等待/睡眠/阻塞状态。
 *  
 * 在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果

线程同步

多个线程执行的不确定性引起执行结果的不稳定

多个线程对账本的共享,会造成操作的不完整性,会破坏数据

记录学习每一天-day24

 代码实现:

public class Thread_Synchronization {
    public static void main(String[] args) {
        A a =new A(10);
        A a1=new A(11);
        Thread t1 = new Thread(new Processor_03(a));
        Thread t2 = new Thread(new Processor_03(a));
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();
    }

}
class Processor_03 implements Runnable {
    A a;
    public Processor_03(A a){
        super();
        this.a=a;
    }

    @Override
    public void run() {
        a.m1();
    }
    
}
class A{
    int i;
    // 方法锁
//        public synchronized void m1()
    public  void m1() {
        System.out.println("-----------");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 代码块锁
        synchronized(this){
            i++;
            System.out.println(Thread.currentThread().getName() + " : " + i);
        }
        System.out.println("——————————");
    }
    public A(int i){
        super();
        this.i = i;
    }
}
 

 除了synchronized以外,还有显式锁 ,它开启和关闭 都是手动的

记录学习每一天-day24

 定时器

记录学习每一天-day24

 多个锁同时使用,可能会导致死锁

死锁


 在执行过程中,都遇到了加锁的功能,从而进入等待状态,导致大家都访问不了
 * 
 * 1 某个线程执行完成,需要 先后 嵌套 锁定 两个对象
 *     2 A线程 先进入第一个对象,并锁定第一个对象,在第一个对象中去嵌套访问并锁定第二个对象
 * 3 B线程,先进入第二个对象,并锁定第二个对象,在第二个对象中去嵌套访问并锁定第一个对象
 *     4 当A线程把第一个对象锁定之后,要去访问第二个对象的时候,
 *             发现已经被B线程锁住了,只能等待B线程交出第二个对象的锁才能执行
 * 5 当B线程把第二个对象锁定之后,要去访问第一个对象的时候,
 *             发现已经被A线程锁住了,只能等待A线程交出第一个对象的锁才能执行
 * 6 因此 导致 A和B都进入等待状态

 代码实现:

public class Thread_DeadLock {
    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = new Object();
        Thread t1 = new T1(o1,o2);
        Thread t2 = new Thread(new T2(o1,o2));
        t1.start();
        t2.start();
    }

}
class T1 extends Thread{
    Object o1;
    Object o2;
    
    public T1(Object o1, Object o2) {
        super();
        this.o1 = o1;
        this.o2 = o2;
    }
    @Override
    public void run() {
            synchronized (o1) {
                System.out.println("t1已进入o1 准备进入o2");
                synchronized (o2) {
                    System.out.println( "t1 执行完成");
                }
            }
    }
}
class T2 extends Thread{
    Object o1;
    Object o2;
    
    public T2(Object o1, Object o2) {
        super();
        this.o1 = o1;
        this.o2 = o2;
    }
    @Override
    public void run() {
        synchronized (o2) {
            System.out.println("t2已进入o2 准备进入后o1");
            synchronized (o1) {
                System.out.println( "t2 执行完成");
            }
        }
    }
}
 

 线程通信

记录学习每一天-day24

 

代码实现过程:

public class Thread_Wait {
    public static void main(String[] args) {
        Num num = new Num();
        Thread t1 = new PrintOdd(num);
        Thread t2 = new PrintEven(num);
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();
    }

}
class PrintOdd extends Thread {
    Num num;
    public PrintOdd(Num num) {
        super();
        this.num = num;
    }
    @Override
    public void run() {
        while (true) {
            num.printOdd();
        }
    }
}
class PrintEven extends Thread {
    Num num;

    public PrintEven(Num num) {
        super();
        this.num = num;
    }

    @Override
    public void run() {
        while (true) {
            num.printEven();
        }
    }
}

class Num {
    //业务类
    int count = 1;
    public synchronized void printOdd() {
        System.out.println(Thread.currentThread().getName() + " : " + count);
        count++;
        // 唤醒所有在当前对象中睡眠的线程
                this.notifyAll();
                try {
                    Thread.sleep(500);
                    // 挂起 交出该对象持有的锁,让其他线程可以执行
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    public synchronized void printEven() {
        System.out.println(Thread.currentThread().getName() + " : " + count);
        count++;
        // 唤醒所有在当前对象中睡眠的线程
        this.notifyAll();
        try {
            Thread.sleep(500);
            // 挂起 交出该对象持有的锁,让其他线程可以执行
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
 

上一篇:day24_字符流丶缓冲流


下一篇:day24_SQL语言(三)DQL