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); //要考虑有异常的情况。。。
}
}