Java2多线程

@

一、基本概念的理解

1、程序、进程、线程

  1. 程序(program):一组指令的集合,一段静态的代码。
  2. 进程(progress):程序的一次执行过程,或正在运行的一个程序。
  3. 线程(thread):一个进程内部的一条执行路径。

2、单核CPU与多个CPU

  1. 单核CPU:只有一个CPU芯片。一个极短的时间内只能执行一个线程任务。由于在线程之间切换的时间极短,给人多线程的假象。
  2. 多核CPU:多个CPU芯片。

3、串行、并行、并发

  1. 串行:一个线程执行完再执行下一个线程。
  2. 并行:多个CPU同时执行多个任务。
  3. 并发:一个CPU同时执行多个任务,交替执行,抢占CPU时间。

二、多线程

1、java中的多线程举例

  • 一个Java应用程序java.exe,其实至少有三个线程:main()主线程,gc() 垃圾回收线程,异常处理线程。当然如果发生异常,会影响主线程。

2、多线程优点

  • 提高应用程序的响应。命令行下,我们一般一个时间只做一件事,但是图形界面下则不是,因此有必要来使用多线程保证各个任务的响应速度。
  • 提高CPU利用率。
  • 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改。比如

3、何时需要多线程

  1. 程序需要同时执行两个或多个任务。
  2. 程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
  3. 需要一些后台运行的程序时。

三、多线程的创建和使用★★★★★

1、方式一:继承Thread类(JDK1.5之前的两种之一)

  1. 代码实现
package com.thread;

public class ThreadTest1 {
    public static void main(String[] args) {
        new MyThread1().start();
    }
}


class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(MyThread1.currentThread().getName() + ":" + i);
        }
    }
}

//当某个线程只适用了一次的时候,也可以使用匿名类匿名对象的方式来创建多线程
package com.thread;

public class ThreadTest2 {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                System.out.println("我是子线程");
            }
        }.start();
    }
}
  1. 步骤总结
1)  定义子类继承Thread类。 
2)  子类中重写Thread类中的run方法。
3)  创建Thread子类对象,即创建了线程对象。 
4)  调用线程对象start方法:启动线程,调用run方法。
  1. 注意:
  • 启动多线程,必须调用start方法。如果自己手动调用run()方法,那么就只是普通方法,没有启动多线程模式
  • 一个线程对象只能调用一次start()方法启动,如果重复调用了,则将抛出以上 的异常“IllegalThreadStateException”。
    • 因此,如果我们想两个线程同时做一件事,要new两个对象
    • 因此,如果我们想两个线程同时做两件事,重写一个run()是不够的,这是我们就要创建2个类继承,然后再分别重写run()。
  1. Thread类中的方法(详细解释看API文档)

  2. 线程的调度:时间片策略、抢占式

    1. Java中,同优先级线程组成先进先出队列(先到先服务),使用时间片策略
    2. 对高优先级,使用优先调度的抢占式策略
  3. 线程的优先级

    1. 优先级等级
    • MAX_PRIORITY:10
    • MIN _PRIORITY:1
    • NORM_PRIORITY:5
    1. 方法
    • getPriority() :返回线程优先值
    • setPriority(int newPriority) :改变线程的优先级

2、方式二:实现Runnable接口(JDK1.5之前的两种之一)

  1. 代码实现

    public class ThreadTest3 {
        public static void main(String[] args) {
            MyThread3 myThread3 = new MyThread3();
    
            Thread t1 = new Thread(myThread3);
            
            t1.start();
        }
    }
    
    class MyThread3 implements Runnable{
    
        @Override
        public void run() {
            System.out.println("我是子线程");
        }
    }
    
    //当某个线程只适用了一次的时候,也可以使用匿名类匿名对象的方式来创建多线程
    new Thread(new Runnable() {
                @Override
                public void run() {
                    
                }
            }).start();
    
  2. 步骤总结

    1. 创建一个实现了Runnable接口的类
    2. 实现类去实现Runnable中的抽象方法:run()
    3. 创建实现类的对象
    4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
    5. 通过Thread类的对象调用start()
    
  3. 比较两种创建线程的方式

    1. 开发中:优先选择:实现Runnable接口的方式

      原因:

      1. 实现的方式没有类的单继承性的局限性
      2. 实现的方式更适合来处理多个线程有共享数据的情况。
    2. 联系:

      1. public class Thread implements Runnable
      2. 相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中。

3、方式三:实现Callable接口

4、方式四:使用线程池(开发中主要是用这个)

四、线程的生命周期

1、线程的生命周期★★★★★

  • 说明
    • 一个线程的最终状态是死亡,不能停在阻塞。

五、线程的同步

1、线程安全问题举例和解决

  • 以卖票窗口为例,三个窗口本来就存在重票、错票(票号小于等于0),只是概率较小。可以通过sleep方法来使这种效果更加明显。这就是线程安全问题
class Window implements Runnable{

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            if (ticket > 0){
                //在这里让刚进入的线程阻塞100ms,错票的概率就会增加
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("售票,票号为: " + ticket);
                //如果在这里让刚进入的线程阻塞100ms,重票的概率就会增加
                ticket--;
            }else{
                break;
            }
        }
    }
}
public class WindowTest {
    public static void main(String[] args) {
        Window w1 = new Window();
        Thread t1 = new Thread(w1);
        Thread t2 = new Thread(w1);
        Thread t3 = new Thread(w1);

        t1.setName("窗口1");
        t1.setName("窗口2");
        t1.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}
  • 解决方案:当一个线程a操作ticket的时候,其他线程不能进来,知道a完事了,及时是a阻塞了,也不能进来。(和上厕所把门锁住一个道理,逃~)在java中用同步机制来解决。
  • 对于继承和实现的方式,同步锁解决线程安全问题时,是重要牢记继承会创建多个对象,一般都要用static来修饰属性和方法的。

2、同步代码块

  1. 语法

    synchronized(锁){
        需要被同步的代码
    }
    
  2. 说明

    1. 锁:即同步监视器,任何一个对象都可以充当锁。但是要求,多个线程必须共用一把锁(就是说,new对象这一步,必须是只发生一次)
    2. 被同步的代码:这一部分是操作共享数据的代码。但是不能包多--->如果我们把while也包起来,就成了一个窗口卖所有的票。
  3. 对window的改进

    1. 对继承的方式的改进
    /*
    说明:
    	1、继承的方式的特点就是我们需要new好几个对象,所以需要这些对象都共享票数和锁,声明为static即可解决这个问题。
    	2、还可以用Window1.class来充当锁。
    */
    
    class Window1 extends Thread{
    
        private static int ticket = 100;
    
        static Object obj = new  Object();
    
        @Override
        public void run() {
            while (true) {
                synchronized (obj) {
                    if (ticket > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("ticket_number=" + ticket);
                        ticket--;
                    }else{
                        break;
                    }
                }
            }
        }
    }
    
    public class Window_Thread_Security1 {
        public static void main(String[] args) {
    
            Window1 w1 = new Window1();
            Window1 w2 = new Window1();
            Window1 w3 = new Window1();
    
            w1.start();
            w2.start();
            w3.start();
        }
    }
    
    1. 对实现方式的改进
    /*
    说明:
    	1、实现的方式的特点是只new了一个类的对象,因此票数和锁自动就是共享的。
    	2、还可以用this来充当锁。
    */
    class Window2 implements Runnable{
    
        private int ticket = 100;
    
        @Override
        public void run() {
            while (true) {
                synchronized (this) {
                    if (ticket > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("ticket_number=" + ticket);
                        ticket--;
                    }else{
                        break;
                    }
                }
            }
        }
    }
    public class Window_Thread_Security2 {
        public static void main(String[] args) {
            Window2 window2 = new Window2();
    
            Thread t1 = new Thread(window2);
            Thread t2 = new Thread(window2);
            Thread t3 = new Thread(window2);
    
            t1.start();
            t2.start();
            t3.start();
        }
    }
    
  4. 优缺点

    1. 优:解决了线程安全问题
    2. 缺:操作同步代码时,只有一个线程参与,相当于是单线程,效率低。

3、同步方法

  1. 语法:synchronized放在方法声明中,表示整个方法是同步方法

    public synchronized void show (String name){
    	//方法体
    }
    
  2. 对window问题的改进

    1. 对继承方式的改建
    class Window3 extends Thread{
    
        private static int ticket = 100;
    
        private static synchronized void show(){//因为我们这里的默认省略了锁,// 如果不加static,锁就是this,这显然多个对象对对应多个锁
            //加了static以后,锁就成了Window3.class,是惟一的锁
                if (ticket > 0) {
    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                    System.out.println("ticket_number=" + ticket);
                    ticket--;
                }
        }
    
        @Override
        public void run() {
            while (true) {
                show();
            }
        }
    }
    
    public class Window_Thread_Security3 {
        public static void main(String[] args) {
    
            Window1 w1 = new Window1();
            Window1 w2 = new Window1();
            Window1 w3 = new Window1();
    
            w1.start();
            w2.start();
            w3.start();
        }
    }
    
    1. 对实现方式的改进
    class Window4 implements Runnable{
    
        private int ticket = 100;
    
        private synchronized void show(){//这时,锁是this,只创建了一个Window4的对象,是唯一的.
            if (ticket > 0) {
    
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                System.out.println("ticket_number=" + ticket);
                ticket--;
            }
        }
    
        @Override
        public void run() {
            while (true) {
                show();
            }
        }
    }
    public class Window_Thread_Security4 {
        public static void main(String[] args) {
            com.thread.Window2 window2 = new com.thread.Window2();
    
            Thread t1 = new Thread(window2);
            Thread t2 = new Thread(window2);
            Thread t3 = new Thread(window2);
    
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

4、死锁

  1. 概念:不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃 自己需要的同步资源,就形成了线程的死锁。出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续。
  2. 尽量避免死锁
    1. 专门的算法、原则。
    2. 尽量减少同步资源的定义
    3. 尽量避免嵌套同步
  3. 死锁的演示
package com.thread3;

public class DeadLock {
    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(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                synchronized (s2){
                    s1.append("b");
                    s2.append("2");

                    System.out.println("s1 = " + s1);
                    System.out.println("s2 = " + 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 = " + s1);
                        System.out.println("s2 = " + s2);
                    }


                }

        }).start();
    }
}
/*
输出结果有哪些可能
    线程1先执行,线程2后执行:ab  12  adcd  1234
    线程2先执行,线程1后执行:cd  34  cdab  3412
    都阻塞:
 */

5、lock

  1. 介绍

    1. 从JDK 5.0开始,Java提供了更强大的线程同步机制——通过显式定义同步锁对象来实现同步。同步锁使用Lock对象充当。(Lock是一个接口)
    2. ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显式加锁、释放锁。
  2. 语法

class A{
    private final ReentrantLock lock = new ReentrantLock();
    
    public void method(){
        lock.lock();//请求锁
        try{
            代码逻辑
        }finnaly{
            lock.unlock();//释放锁
        }
    }
}
  1. 用Lock解决window卖票的线程安全问题
class Window5 extends Thread{

    private static int ticket = 100;

    private static final ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
			lock.lock();
            try {
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("ticket_number=" + ticket);
                    ticket--;
                }else{
                    break;
                }
            } finally {
                lock.unlock();
            }
        }
    }
}

public class LockTest {
    public static void main(String[] args) {

        Window5 w1 = new Window5();
        Window5 w2 = new Window5();
        Window5 w3 = new Window5();

        w1.start();
        w2.start();
        w3.start();
    }
}
  1. 面试题
    1. synchronized 与 Lock的异同?
      1. 同:都是用于解决线程安全问题
      2. 异:①、Lock是显示锁,需要我们自己手动开启和关闭;synchronized是隐式锁,出了作用域就会自动释放锁。②、Lock只有代码块锁,synchronized有代码块锁和方法锁。③、Lock锁性能好,拓展性好。
    2. 如何解决线程安全问题,有几种方式?
      1. 两大类。一类是Lock,一类是synchronized
  2. 开发中优先使用:Lock--->同步代码块--->同步方法

六、线程的通信

  1. 线程通信的例子:使用两个线程打印 1-10。线程1,线程2 交替打印
//1、要先分析是不是多线程为题;
//2、在分析是否有共享数据,有---同步机制来解决

class MyPrinter implements Runnable {

    private int number = 1;

    @Override
    public synchronized void run() {
        while (true) {
            this.notify();
            if (number <= 10) {
//                this.notify();//如果我把notify放在这里,程序就不会自动结束了?  因为,放在这里,//最后一个循环的情况下,打印机二带着10进入,可以notify打印机一,再下一轮,打印机一拿着11
                //,无法进入if,无法notify打印机二,打印机二就一直阻塞在那里
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + number);
                number++;

                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }
}

public class ThreadCommunicationTest {
    public static void main(String[] args) {
        MyPrinter myPrinter = new MyPrinter();
        Thread t1 = new Thread(myPrinter);
        Thread t2 = new Thread(myPrinter);

        t1.setName("打印机一");
        t2.setName("打印机二");

        t1.start();
        t2.start();
    }
}
  1. 涉及到的三个方法:
    1. wait():当前线程阻塞,并释放锁
    2. notify():当前线程唤醒被wait的其他一个线程,谁的优先级高就唤醒谁
    3. notifyAll():当前线程唤醒all被wait的线程
  2. 对这三个方法的说明
    1. 个方法必须使用在同步代码块或同步方法中。
    2. 三个方法的调用者必须是同步代码块或同步方法中的同步监视器。否则,会出现IllegalMonitorStateException异常。
      1. 我这里用的是this;如果我自己new一个Object类,那么this就要改为Object类的对象。
    3. 三个方法是定义在java.lang.Object类中。
  3. 面试题:sleep() 和 wait()的异同?★★★★★
    1. 同:两者都可以使线程阻塞
    2. 异:
      1. 声明的位置不同:sleep()是声明在Thread类中;wait()是声明在Object类中
      2. 使用的位置不同:sleep()使用在任意位置;wait()使用在同步代码块或同步方法中
      3. 使用完了以后做的事不同:sleep()不会释放锁,wait()会释放锁

七、生产者和消费者问题

/**
 * 线程通信的例子:使用两个线程打印 1-100。线程1,线程2 交替打印
 *
 * 涉及到的三个方法:
 * wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
 * notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
 * notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。
 *
 * 说明:
 * 1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。
 * 2.wait(),notify(),notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器。
 *    否则,会出现IllegalMonitorStateException异常
 * 3.wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中。
 *
 * 面试题:sleep() 和 wait()的异同?
 * 1.相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
 * 2.不同点:1)两个方法声明的位置不同:Thread类中声明sleep(),Object类中声明wait()
 *          2)调用的要求不同:sleep()可以在任何需要的场景下调用。 wait()必须使用在同步代码块或同步方法中
 *          3)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。
 *
 * @author shkstart
 * @create 2019-02-15 下午 4:21
 */
class Number implements Runnable{
    private int number = 1;
    private Object obj = new Object();
    @Override
    public void run() {

        while(true){

            synchronized (obj) {

                obj.notify();

                if(number <= 100){

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ":" + number);
                    number++;

                    try {
                        //使得调用如下wait()方法的线程进入阻塞状态
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }else{
                    break;
                }
            }

        }

    }
}


public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

        t1.setName("线程1");
        t2.setName("线程2");

        t1.start();
        t2.start();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 连接 连接池产生原因 连接池实现原理 小结 TEMPERANCE:Eat not to dullness;drink not to elevation.节制
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。-- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelC
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个人在用”。哪怕只是throw了一个新的Exception。哈哈,这是我犯的错误。一、接口和抽象类类,即一个对象。先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类)。官方定义让人费解,但是记忆方法是也不错的 —包含抽象方法的类叫做抽象类。接口
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket一、引子文件,作为常见的数据源。关于操作文件的字节流就是 —FileInputStream&amp;FileOutputStream。
作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节。交流QQ群:【编程之美 365234583】http://qm.qq.com/cgi-bin/qm/qr?k=FhFAoaWwjP29_Aonqz
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程与多线程 线程是什么? 线程(Thread)是一个对象(Object)。用来干什么?Java 线程(也称 JVM 线程)是 Java 进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。 Ja
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket在面向对象编程中,编程人员应该在意“资源”。比如?1String hello = &quot;hello&quot;; 在代码中,我们
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 《程序兵法:Java String 源码的排序算法(一)》 文章工程:* JDK 1.8* 工程名:algorithm-core-le
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 一、父子类变量名相同会咋样? 有个小故事,今天群里面有个人问下面如图输出什么? 我回答:60。但这是错的,答案结果是 40 。我知错能改,然后说了下父子类变
作者:泥瓦匠 出处:https://www.bysocket.com/2021-10-26/mac-create-files-from-the-root-directory.html Mac 操作系统挺适合开发者进行写代码,最近碰到了一个问题,问题是如何在 macOS 根目录创建文件夹。不同的 ma
作者:李强强上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算。这一讲,泥瓦匠带你走进Java中的进制详解。一、引子在Java世界里,99%的工作都是处理这高层。那么二进制,字节码这些会在哪里用到呢?自问自答:在跨平台的时候,就凸显神功了。比如说文件读写,数据通信,还
1 线程中断 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want需求 项目在设计表的时候,要处理并发多的一些数据,类似订单号不能重复,要保持唯一。原本以为来个时间戳,精确到毫秒应该不错了。后来觉得是错了,测试环境下很多一
纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 加微信:bysocket01
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want.文章Points:1、介绍RESTful架构风格2、Spring配置CXF3、三层初设计,实现WebService接口层4、撰写HTTPClient 客户
Writer :BYSocket(泥沙砖瓦浆木匠)什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道“就一个回调…”。此时千万个草泥马飞奔而过(逃哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉。不妨总结总结。一、什么是回调回调,回调。要先有调用,才有调用者和被调用者之间的回调。所以在百
Writer :BYSocket(泥沙砖瓦浆木匠)一、什么大小端?大小端在计算机业界,Endian表示数据在存储器中的存放顺序。百度百科如下叙述之:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加
What is a programming language? Before introducing compilation and decompilation, let&#39;s briefly introduce the Programming Language. Programming la
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket泥瓦匠喜欢Java,文章总是扯扯Java。 I/O 基础,就是二进制,也就是Bit。一、Bit与二进制什么是Bit(位)呢?位是CPU
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocket一、前言 泥瓦匠最近被项目搞的天昏地暗。发现有些要给自己一些目标,关于技术的目标:专注很重要。专注Java 基础 + H5(学习) 其他操作系统,算法,数据结构当成课外书博览。有时候,就是那样你越是专注方面越