LOADING

加载过慢请开启缓存 浏览器默认开启

2023/11/16

java学习

终于学完java多线程了,大概了解了线程同步、死锁、线程池等概念还有一些常用对象,然后还搞了个java的爬虫(java的http编程)

package java_thread;

public class death_sync {
    public static int count=0;
    public static final Object lock_1=new Object();  //最好是常量
    public static final Object lock_2=new Object();
    public static synchronized void add(){
        count+=1;
        add2();
    }
    public static synchronized void add2(){  //java的锁是可重入锁,同一个线程可以多次获得某个锁
        count+=1;
        System.out.println("成功获得两次锁");
    }

    public static void paradox1()throws InterruptedException{
        synchronized (lock_1){
            System.out.println("paradox1获得锁1,等待锁2");
            synchronized (lock_2){
                System.out.println("paradox1获得锁2");
            }
        }
    }

    public static void paradox2()throws InterruptedException{
        synchronized (lock_2){
            Thread.sleep(1000);
            System.out.println("paradox2获得锁2,等待锁1");  //互相多次获得锁就可能导致死锁
            synchronized (lock_1){
                System.out.println("paradox2获得锁1");
            }
        }
    }
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            death_sync.add();
        });
        t1.start();
        Thread t2 = new Thread(() -> {
            try {
                death_sync.paradox1();
            } catch (Exception ignored) {
            }
        });
        //Thread t3=new Thread(death_sync::paradox2); 在Java中,lambda表达式或方法引用不允许!!抛出受检异常。
        Thread t3 = new Thread(() -> {
            try {
                death_sync.paradox2();
            } catch (Exception ignored) {
            }
        });
        t2.start();
        t3.start();
    }

}
package java_thread;

import java.util.LinkedList;
import java.util.Queue;

public class wait_notify {
    public static void main(String[] args) {
        TaskQueue taskQueue=new TaskQueue();
        for(int i=0;i<5;i++){
            int finalI = i;
            Thread t=new Thread(){
                @Override
                public void run(){
                    int o=2;
                    for(;o>0;o--){  //每个线程只会接收并处理2个任务
                        try {
                            taskQueue.gettask(finalI);
                        }catch (Exception e){return;}
                    }
                }
            };
            t.start();
        }
        for(int i=0;i<10;i++){
            int finalI = i;
            Thread add=new Thread(){
                public void run(){
                    String s_add="添加任务%d".formatted(finalI+1);
                    System.out.println(s_add);
                    taskQueue.addtask(s_add);
                    try {
                        Thread.sleep(1000);
                    }catch (Exception e){}
                }

            };
            add.start();
        }
    }
}
class TaskQueue{
    Queue<String> tasks=new LinkedList<>();
    public synchronized void addtask(String s){
        this.tasks.add(s);
        this.notifyAll();  //将当前正在等待wait锁对象的线程激活(使wait返回值)
    }

    public synchronized String gettask(int num)throws InterruptedException{
        while (tasks.isEmpty()){
            this.wait(); //释放当前获得的锁对象,并进入睡眠状态(线程运行卡在这一步,知道被唤醒)
        }
        System.out.println("线程%d正在执行任务:".formatted(num)+tasks.peek());
        return tasks.remove();
    }

}
package java_thread;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.*;

public class wait_notify_threadpool {
    public static void main(String[] args) {
        TaskQueue2 taskQueue2=new TaskQueue2();
        ExecutorService executor= Executors.newFixedThreadPool(5);
        for(int i=0;i<5;i++){
            Future<String> future=executor.submit(new get_thread(i+1,taskQueue2));
        }
        executor.shutdown(); //通过线程池获得的线程不会在执行完run函数后自动结束,需要主动去shutdown()才会结束(主程序不会在执行shutdown后立刻关闭,而是会等待run函数执行完成)
//        for(int i=0;i<5;i++){
//            int finalI = i;
//            Thread t=new Thread(){
//                @Override
//                public void run(){
//                    int o=2;
//                    for(;o>0;o--){  //每个线程只会接收并处理2个任务
//                        try {
//                            taskQueue.gettask(finalI);
//                        }catch (Exception e){return;}
//                    }
//                }
//            };
//            t.start();
//        }
        for(int i=0;i<10;i++){
            int finalI = i;
            Thread add=new Thread(){
                public void run(){
                    String s_add="任务%d".formatted(finalI+1);
                    System.out.println("添加"+s_add);
                    taskQueue2.addtask(s_add);
                    try {
                        Thread.sleep(100);
                    }catch (Exception e){}
                }

            };
            add.start();
        }
    }
}
class TaskQueue2 {
    Queue<String> tasks=new LinkedList<>();
    public synchronized void addtask(String s){
        this.tasks.add(s);
        this.notifyAll();  //将当前正在等待wait锁对象的线程激活(使wait返回值)
    }

    public synchronized String gettask(int num)throws InterruptedException{
        while (tasks.isEmpty()){
            this.wait(); //释放当前获得的锁对象,并进入睡眠状态(线程运行卡在这一步,知道被唤醒)
        }
        System.out.println("线程%d正在执行任务:".formatted(num)+tasks.peek());
        Thread.sleep(1000);
        return tasks.remove();
    }

}

class get_thread implements Callable<String> {  //Callable相比Runnable,多了可选的返回值
    int num;
    TaskQueue2 task;
    public get_thread(int num,TaskQueue2 task){
        this.num=num;
        this.task=task;
    }
    @Override
    public String call(){
        int o=2;
        for(;o>0;o--){  //每个线程只会接收并处理2个任务
            try {
              String s=this.task.gettask(this.num);
              // return s+"执行完成"; 有return会提起结束!!!
            }catch (Exception ignored){}
        }
        return "%d线程任务完成".formatted(num);  //要考虑有异常的情况。。。
    }
}