栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java基础笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java基础笔记

一、 java基础 1. java多线程基础 1) 多线程的创建方式 1.多线程创建方式1
package com.qyl.springboot.controller;



// 1.创建一个子类类继承Thread
class MyThread extends Thread{
    //2.在子类中重写Thread的run()方法   线程要做的事写到run()方法中
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0){
                System.out.println(i+"---"+Thread.currentThread().getName());
            }
        }
    }
};

public class ThreadTest {

    public static void main(String[] args) {
        // 3.创建该子类的对象
                //主线程执行
        MyThread myThread = new MyThread();
        MyThread myThread1 = new MyThread();
        //4.通过此对象调用start方法
                //创建出来的线程执行
        
        myThread.start();
        myThread1.start();//乡启动多个就多创建对象即可

        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0){
                System.out.println(i+ " ++++++++++++++-"+Thread.currentThread().getName());
            }
        }
				//这种方法也可以   匿名子类
        System.out.println("/");
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    if (i % 2 != 0){
                        System.out.println(Thread.currentThread().getName()+""+ i );
                    }
                }
            }
        }.start();
    }
}

输出结果:

48---Thread-0
78---Thread-1
50---Thread-0
18 ++++++++++++++-main
52---Thread-0
80---Thread-1
82---Thread-1
84---Thread-1
2. 多线程创建方式2

实现Runnable接口

1.创建一个实现了Run那边了接口的类

2.实现类去实现Runable中的抽象方法

3.创建实现类的对象

4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象

5.通过Thread类的对象调用start()方法

package com.qyl.springboot.controller;



//1.创建一个实现了Run那边了接口的类
class MyRunnable implements Runnable{
    //2.实现类去实现Runable中的抽象方法
    @Override
    public void run() {

        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0){
                System.out.println(""+i+ " ++++++++++++++-"+Thread.currentThread().getName());
            }
        }
    }
}
public class RunableTest {
    public static void main(String[] args) {
        //3.创建实现类的对象
        MyRunnable m1 = new MyRunnable();
        //4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
        Thread thread = new Thread(m1);
        thread.setName("liudeh");
        thread.start();
        Thread t2 = new Thread(m1);
        t2.setName("liudsssssssssseh");
        t2.start();
    }

}
2.线程生命周期
    创建 调用start()就绪 sleep()时间到,join()结束,获取同步锁,notify()/notifyALL(),resume()阻塞 失去cpu执行权,或者yield()运行 sleep(),join(),等待同步锁,wait(),suspend()死亡 执行完run(),调用stop(),出现Error/Exception且没处理
3.线程同步 1.同步代码块
/**
 * 线程同步与安全
 * 处理共享数据的时候会出现线程安全问题
 * 加锁解决
 * 4.在java中,通过同步机制来解决线程安全问题
 * 方式一 : 同步代码块
 *  synchronized (同步监视器) {
 *      //需要被同步的代码 (吃操作共享数据的代码就是需要被同步的代码)
 *  }
 *  说明:  1.(吃操作共享数据的代码就是需要被同步的代码)
 *        2.同步监视器就是 锁 任何类的对象都能充当锁
 *          锁的要求 : 多个线程供用同一把锁
 *          哪怕你用一个狗 dag对象都可以
 * 方式二 : 同步方法
 *
 *
 * 5.同步的方式虽然解决了线程安全
 *  缺点是同步代码块里面是单线程
 */
package com.qyl.java;


class Window implements Runnable{
    private int titck = 100;
    Object object = new Object();
    @Override
    public void run() {
      while (true){
          //同步代码块
          synchronized(object){
              if (titck>0){
                  System.out.println(Thread.currentThread().getName()+" 卖票-----票号码为: " + titck );
                  titck--;
              }else {
                  break;
              }
          }
      }
    }
}


public class SyncThread {
    public static void main(String[] args) {
        Window m1 = new Window();
        Thread t1 = new Thread(m1);
        Thread t2 = new Thread(m1);
        Thread t3 = new Thread(m1);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

注意:implement Runnable 的时候 this(当前对象 ) 就可以当做锁 extends Threads的时候 不行

2.同步方法
// 1.一种情况可以直接把run改为同步的,但是要注意场景
class Window implements Runnable{
    private int titck = 100;
    Object object = new Object();
    @Override
    public synchronized void run() {
      while (true){
          //同步代码块
          synchronized(this){

              if (titck>0){
                  System.out.println(Thread.currentThread().getName()+" 卖票-----票号码为: " + titck );
                  titck--;
              }else {
                  break;
              }
          }
      }
    }
}

1.同步方法解决Runnable
package com.qyl.java;


class Window implements Runnable{
    private int titck = 100;
    Object object = new Object();
    @Override
    public  void run() {
      while (true){
            sync();
      }
    }
    private synchronized void sync (){ //同步监视器就是this
        //同步代码块

            if (titck>0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+" 卖票-----票号码为: " + titck );
                titck--;
            }
    }
}


public class SyncThread {
    public static void main(String[] args) {
        Window m1 = new Window();
        Thread t1 = new Thread(m1);
        Thread t2 = new Thread(m1);
        Thread t3 = new Thread(m1);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
2.同步方法解决thread
package com.qyl.java;


class Windows extends Thread {
    private static int tickets = 100;
    private static Object object = new Object();

    @Override
    public void run() {
        while (true) {
            //同步代码块
            show();
        }
    }
private static synchronized void show(){ //加个static 就可以了
    if (tickets > 0) {
        try {
            sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 卖票-----票号码为: " + tickets);
        tickets--;
    }
}
}

public class extendsThread {
    public static void main(String[] args) {
        Windows w1 = new Windows();
        Windows w2 = new Windows();
        Windows w3 = new Windows();
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");
        w1.start();
        w2.start();
        w3.start();
    }
}

4.Thread 的常用方法介绍: 1) start():

启动当前线程,调用当前线程的run()方法 。

2) run():

通常是重写Thread 的run()方法 将线程要做的事情声明在该方法中

3) currentThread() :

Thread 的静态方法 获取到当前线程

4)getName() setName():

给线程名字的方法

package com.qyl.springboot.controller;class MyThread1 extends Thread{    @Override    public void run() {        for (int i = 0; i < 100; i++) {            if(i % 2 == 0 ){ 						try {                    sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                //Thread.currentThread().setName("lalala"); 线程命名 方式1                System.out.println(Thread.currentThread().getName()+"*******"+i);            }        }    }}public class ThreadTest1 {    public static void main(String[] args) {        MyThread1 myThread1 = new MyThread1();        //线程命名 方式2        myThread1.setName("huren");        myThread1.start();        //给主线程命名        Thread.currentThread().setName("zongguanjun");        for (int i = 0; i < 100; i++) {            if(i % 2 == 0 ){                //Thread.currentThread().setName("lalala"); 线程命名                System.out.println(Thread.currentThread().getName()+"*******///"+i);            }        }    }}------------------------通过构造器命名线程package com.qyl.springboot.controller;class MyThread1 extends Thread{    @Override    public void run() {        for (int i = 0; i < 100; i++) {            if(i % 2 == 0 ){                //Thread.currentThread().setName("lalala"); 线程命名 方式1                System.out.println(Thread.currentThread().getName()+"*******"+i);            }            if(i % 20 == 0){                yield();            }        }    }    //线程命名方式3  通过构造器命名    public MyThread1(String name){        super(name);    }}public class ThreadTest1 {    public static void main(String[] args) {        MyThread1 myThread1 = new MyThread1("sssssss");        //线程命名 方式2        myThread1.setName("huren");        myThread1.start();        //给主线程命名        Thread.currentThread().setName("zongguanjun");        for (int i = 0; i < 100; i++) {            if(i % 2 == 0 ){                //Thread.currentThread().setName("lalala"); 线程命名                System.out.println(Thread.currentThread().getName()+"*******///"+i);            } 	        }    }}
5)yiel ():

释放当前cpu的执行权

6)join ():

在线程a中调用线程b的join()方法,此时线程a进入阻塞状态,等b执行完之后,a结束阻塞继续执行

7) stop():

强制结束该线程,不推荐使用

8) sleep(lang millitime):

当前线程睡眠指定的一段时间

9) isAlive()

判断当前线程是否存活

10)property()get,set

线程的优先级 1-10 默认5

public void  newRunnableMethod () {    		new Thread(new Runnable() {        @Override        public void run() {            // 存放所有openid            List openids = new ArrayList<>();            List usersGuid = new ArrayList<>();            SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);            Task_Info_News_ReadMapper mapper = sqlSession.getMapper(Task_Info_News_ReadMapper.class);            try{                // 组装info_news_read 表所需要的数据,并存入数据库中                for(int i = 0; i< list.size();i++){                    String strUserGuid =  (String)list.get(i).get("strUserGuid");                    // 通过临时存放usersGuid,去重(对根据范围查出数据进行去重)                    if(!usersGuid.contains(strUserGuid)){                        usersGuid.add(strUserGuid);                        // 获取openid                        Object strOpenid = list.get(i).get("strOpenid");                        // 如果openid不为空,则放入openids集合中(用来推送模板消息)                        if(strOpenid != null){                            openids.add(strOpenid.toString());                        }                        list.get(i).put("strGuid", UUID.randomUUID().toString());                        list.get(i).put("strNewsGuid",info_News.getStrGuid());                        list.get(i).put("strCreator",info_News.getStrCreator());                        list.get(i).put("dtCreateTime", info_News.getDtCreateTime());                        mapper.insertMap(list.get(i));                    }                    if(i % 1000 == 0 || i == list.size() - 1){                        sqlSession.commit();                        sqlSession.clearCache();                    }                }            }catch (Exception e) {                logger.info("事物已回滚");                loggerErr.info("发布任务失败 ==>" + e.getMessage());                sqlSession.rollback();                e.printStackTrace();            }finally {                sqlSession.close();            }            PropertiesUtils utils = null;            try {                utils = new PropertiesUtils("global/param_hexi.properties");            } catch (Exception e) {                logger.info("global/param_hexi.properties 文件找不到");                e.printStackTrace();                return;            }            // 微信模板消息,任务的模板id            if(openids.size() > 0){                String template_id = utils.getProperty("template_id");                sendNewsToWebchatUser(template_id, openids, info_News);            }        }    }).start();}

//不同的写法

package com.qyl.java;class MyThreadRunnable implements Runnable{    @Override    public void run() {        for (int i = 0; i < 100; i++) {            if (i % 2 == 0){                System.out.println(Thread.currentThread().getName() + "=================" +i);            }        }    }}public class SyncThreadTest {    public static void main(String[] args) {        MyThreadRunnable m1 = new MyThreadRunnable();        Thread t1 = new Thread(m1);        t1.setName("子线程1");        t1.start();        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 100; i++) {                    if (i % 2 != 0){                        Thread.currentThread().setName("主线程");                        System.out.println(Thread.currentThread().getName() + "=================" +i);                    }                }            }        }).start();    }}
5.使用同步机制将单例模式中的懒汉式改写为线程安全的 1.效率较低的方式
package com.qyl.java;public class BankTest {}class Bank{    private Bank(){}    private static Bank instance = null;    public static  Bank getInstance(){ //加上synchronized就变成线程安全的了        synchronized () {            if (instance == null){                instance = new Bank();            }            return instance;        }    }}
2.效率高点
package com.qyl.java;public class BankTest {}class Bank{    private Bank(){    }    private static Bank instance = null;    public static  Bank getInstance(){ //加上synchronized就变成线程安全的了        if (instance == null) {            synchronized (Bank.class) {                if (instance == null) {                    instance = new Bank();                }            }        }        return instance;    }}
6.线程死锁问题 1.死锁案例
package com.qyl.java;public class SiSuo {    public static void main(String[] args) {        StringBuffer s1 = new StringBuffer();        StringBuffer s2 = new StringBuffer();        new Thread(){            @Override            public void run() {               synchronized (s1){                   s1.append("a");                   s2.append("1");                   try {                       Thread.sleep(100);                   } catch (InterruptedException e) {                       e.printStackTrace();                   }                   synchronized (s2){                       s1.append("b");                       s2.append("2");                       System.out.println(s1);                       System.out.println(s2);                   }               }            }        }.start();        new Thread(new Runnable() {            @Override            public void run() {                synchronized (s2){                    s1.append("c");                    s2.append("3");                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    synchronized (s1){                        s1.append("d");                        s2.append("4");                        System.out.println(s1);                        System.out.println(s2);                    }                }            }        }).start();    }}
2.解决线程安全问题三 Lock锁

Inspection ‘在使用阻塞等待获取锁的方式中,必须在try代码块之外,并且在加锁方法与try代码块之间没有任何可能抛出异常的方法调用,避免加锁成功后,在finally中无法解锁。
说明一:如果在lock方法与try代码块之间的方法调用抛出异常,那么无法解锁,造成其它线程无法成功获取锁。
说明二:如果lock方法在try代码块之内,可能由于其它方法抛出异常,导致在finally代码块中,unlock对未加锁的对象解锁,它会调用AQS的tryRelease方法(取决于具体实现类),抛出IllegalMonitorStateException异常。
说明三:在Lock对象的lock方法实现中可能抛出unchecked异常,产生的后果与说明二相同。’ options

package com.qyl.java;import java.util.concurrent.locks.ReentrantLock;class WindowLock implements Runnable{    private int titck = 100;    //1.实例化一个lock    private ReentrantLock lock = new ReentrantLock();    @Override    public void run() {        while (true){            try {                lock.lock();                //2.调用lock()                if (titck> 0){                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println(Thread.currentThread().getName()+" 卖票-----票号码为: " + titck );                    titck--;                } else {                    break;                }            } finally {                //调用解锁方法                lock.unlock();            }        }    }}public class LockTest {    public static void main(String[] args) {        WindowLock m1 = new WindowLock();        Thread t1 = new Thread(m1);        Thread t2 = new Thread(m1);        Thread t3 = new Thread(m1);        t1.setName("窗口1");        t2.setName("窗口2");        t3.setName("窗口3");        t1.start();        t2.start();        t3.start();    }}
7.wait() notify() 1.两个线程交叉打印100以内的数
package com.qyl.springboot.controller;

//    2个线程交叉打印100以内的数字
class WaitNotify implements Runnable{
    private int number = 1;
    @Override
    public void run() {
        while (true){
            synchronized (this) {
                //唤醒全部线程
                //notifyAll();
                //唤醒线程
                notify();
                if (number<=100){
                    //睡眠 不释放线程 不释放锁
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"  ---打印了 : "+number);
                    number++;
                    //等待  但是释放线程 释放锁
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    break;
                }
            }
        }
    }
}
public class WaitNotifyTest {
    public static void main(String[] args) {
        WaitNotify w1 = new WaitNotify();
        Thread t1 = new Thread(w1);
        Thread t2 = new Thread(w1);
        t1.setName("线程1 +++++: ");
        t2.setName("线程2 -----: ");
        t1.start();
        t2.start();
    }
}

2.wait(),notify(), notifyAll()

只能用在同步代码块或者方法中 lock不能用

并且调用者必须是同步监视器

这三个方法是定义在对象Object中的 所以都可以用对象调

3.sleep() 和wait()区别

    相同点:都可以使得当前线程进入阻塞状态

    不同点: 1) Thread类中声明Sleep() ,Object类中声明Wait()

    ​ 2) sleep()不会释放锁,wait() 会

    ​ 3.)sleep ()在任何场景都可调用,wait只能在同步代码中调用

8.测试题 1.存钱 ,两个人 公用一个账户,各村三次 每次1000 方法一:
package com.qyl.springboot.controller;


public class AccountTest {
    public static void main(String[] args) {
        //定义初始化的账户
        Account account = new Account(1000);
        //声明两个对象 去开线程
        Customer c1 = new Customer(account);
        Customer c2 = new Customer(account);
        c1.setName("甲");
        c2.setName("乙");
        c1.start();
        c2.start();
    }
}


class Account {
    //声明账户余额
    private double balance;
    //构造器
    public Account(double balance) {
        this.balance = balance;
    }
    //往里面存钱的方法
        //加synchronize 同步
    public synchronized void cunQian (double atm){
        if ((atm>0)){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("当前余额: "+balance);
            balance += atm;
            System.out.println(Thread.currentThread().getName()+"  : 存了 "+atm+" 元,已到账.当前余额为"+balance+"员");
        }
    }
}
//用户类,继承Thread
class Customer extends Thread{
    //注入 Account
    private Account account;
    //构造器
    public Customer(Account account) {
        this.account = account;
    }
    //子类重写父类Run方法
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            //调用存钱方法
            account.cunQian(1000);
        }
    }
}
方法二:
package com.qyl.springboot.javaTest;

public class CustomerQyl extends Thread{
    private AccountQyl accountQyl;

    public CustomerQyl(AccountQyl accountQyl) {
        this.accountQyl = accountQyl;
    }

    @Override
    public  void run() {
        for (int i = 0; i < 4; i++) {

          String s =  accountQyl.Pay(1000);
            System.out.println(Thread.currentThread().getName()+"  ***  "+s);
        }
    }
}
package com.qyl.springboot.javaTest;

public class AccountQyl {
    private double balance;

    public AccountQyl(double balance) {
        this.balance = balance;
    }

    public synchronized String Pay (double atm){
        if (atm>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("当前余额: "+balance);
            balance += atm;
            System.out.println(Thread.currentThread().getName()+"  : 存了 "+atm+" 元,已到账.当前余额为"+balance+"员");
        }
        return "存钱成功";
    }
}
package com.qyl.springboot.javaTest;

public class testSync {
    public static void main(String[] args) {
        AccountQyl accountQyl = new AccountQyl(300);
        CustomerQyl c1 = new CustomerQyl(accountQyl);
        CustomerQyl c2 = new CustomerQyl(accountQyl);
        c1.setName("甲");
        c2.setName("乙");
        c1.start();
        c2.start();
    }
}
2.java 递归
package com.esint.jm.wx_hxpublic.util;
//递归 汉诺塔
public class QylDiGuiTest {
    static int times = 0;
    public  static void  move (int num , char source , char dest){
        System.out.println("第"+(++times)+"步骤  "+num +" 号盘子从 "+source+" 柱子到 "+dest+"柱子");
    }
    public static void hnt (int n,char source,char mid,char dest){
        if (1 == n){
            move(n,source,dest);
        }else {
            hnt(n-1,source,dest,mid);
            move(n,source,dest);
            hnt(n-1,mid,source,dest);
        }
    }

    public static void main(String[] args) {
        hnt(5,'A','B','C');
    }

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/736808.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号