Java框架/基础相关

Struts:Action

Spring,Spring Boot

Hibernate:
Hibernate是开源的一个ORM(对象关系映射)框架
Hibernate对JDBC访问数据库的代码做了轻量级封装

Java Persistence API (JPA)

H2: in-memory database(),包名:com.h2database

Model、Dao、

MyBatis:
主要使用XML配置。

Thread的join()方法

主线程等待子线程的终止。也就是说主线程的代码块中,如果碰到了t.join()方法,此时主线程需要等待(阻塞),
等待子线程结束了(Waits for this thread to die.),才能继续执行t.join()之后的代码块。
示例:https://www.cnblogs.com/skywang12345/p/3479275.html
这里使用了一个延时for循环模拟长时间的执行操作。

public class JoinTest{

    public static void main(String[] args){
        /*
        try {
            ThreadA t1 = new ThreadA("t1"); // 新建“线程t1”

            t1.start();                     // 启动“线程t1”
            t1.join();                        // 将“线程t1”加入到“主线程main”中,并且“主线程main()会等待它的完成”
            System.out.printf("%s finish\n", Thread.currentThread().getName()); 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        */

        ThreadA t1 = new ThreadA("t1"); // 新建“线程t1”
        t1.start();
        System.out.printf("%s finish\n", Thread.currentThread().getName());
    }

    static class ThreadA extends Thread{

        public ThreadA(String name){
            super(name);
        }
        public void run(){
            System.out.printf("%s start\n", this.getName());

            // 延时操作
            for(int i=0; i <1000000; i++)
               ;

            System.out.printf("%s finish\n", this.getName());
        }
    }
}

当不注释掉注释时,主线程main的finish方法会等待子线程t1执行完再执行:
在这里插入图片描述
当注释掉注释时,主线程main的finish方法会在子线程t1前执行:
在这里插入图片描述
哪个Thread对象调用的join(),main线程就等待哪个子线程执行完成。

Thread的run()方法和start()方法的区别

示例:https://www.cnblogs.com/skywang12345/p/3479083.html

// Demo.java 的源码
class MyThread extends Thread{
    public MyThread(String name) {
        super(name);
    }

    public void run(){
        System.out.println("[*] 某线程:" + Thread.currentThread().getName()+" is running");
    }
};

public class Demo {
    public static void main(String[] args) {
        Thread mythread=new MyThread("mythread");

        System.out.println("[*] 某线程:" + Thread.currentThread().getName()+" 调用 mythread.run()");
        mythread.run();

        System.out.println("[*] 某线程:" + Thread.currentThread().getName()+" 调用 mythread.start()");
        mythread.start();
    }
}

在这里插入图片描述

可见如果在main方法中直接调用mythread对象的run方法,则其实是main线程里调用了另外一个对象的某个方法而已。而如果是在main方法中调用mythread对象的start方法,则会先开启一个线程mythread,然后再执行其run方法。

synchronized原理

synchronized代码块

例如,synchronized(obj)就获取了“obj这个对象”的同步锁。
通过同步锁,我们可以互斥地访问某方法/对象。
同步锁的作用体现在:某一时刻,某线程A已经获取到了“obj这个对象”的同步锁,在执行一些操作。如果这个时候某线程B也尝试获取“obj这个对象”的同步锁,则会失败。

示例:https://www.cnblogs.com/skywang12345/p/3479202.html

class MyRunable implements Runnable {

    @Override
    public void run() {
        //synchronized(this) {
            try {
                for (int i = 0; i < 5; i++) {
                    Thread.sleep(1000); // 休眠1000ms
                    System.out.println(Thread.currentThread().getName() + " loop " + i);
                }
            } catch (InterruptedException ie) {
            }
        //}  
    }
}

class Demo1_1 {

    public static void main(String[] args) {
        Runnable demo = new MyRunable();     // 新建“Runnable对象”

        Thread t1 = new Thread(demo, "t1");  // 新建“线程t1”, t1是基于demo这个Runnable对象
        Thread t2 = new Thread(demo, "t2");  // 新建“线程t2”, t2是基于demo这个Runnable对象
        t1.start();                          // 启动“线程t1”
        t2.start();                          // 启动“线程t2” 
    }
}

可见,加了之后,t2会等待t1结束之后才会执行。
在这里插入图片描述
而不加的话,t2会在t1执行过程中就执行。
在这里插入图片描述

这里之所以使用synchronized(this)之后,可以将两个线程互斥,是因为这两个Thread都使用了demo这个对象的run方法。

而如果修改示例代码如下:

class MyThread extends Thread {

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        //synchronized(this) {
            try {
                for (int i = 0; i < 5; i++) {
                    Thread.sleep(1000); // 休眠100ms
                    System.out.println(Thread.currentThread().getName() + " loop " + i);
                }
            } catch (InterruptedException ie) {
            }
        //}  
    }
}

class Demo1_2 {

    public static void main(String[] args) {
        Thread t1 = new MyThread("t1");  // 新建“线程t1”
        Thread t2 = new MyThread("t2");  // 新建“线程t2”
        t1.start();                          // 启动“线程t1”
        t2.start();                          // 启动“线程t2” 
    }
}

这里使用的是两个不同的Thread,没有共享一个Runnerable对象。所以synchronized功能没有发挥到作用。
在这里插入图片描述

synchronized方法 和 synchronized代码块

“synchronized方法”是用synchronized修饰的方法,而 “synchronized代码块”则是用synchronized修饰的代码块。

synchronized方法示例

public synchronized void foo1() {
    System.out.println("synchronized methoed");
}

synchronized代码块

public void foo2() {
    synchronized (this) {
        System.out.println("synchronized methoed");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值