java学习笔记10

2018-11-10  本文已影响0人  海洋_5ad4

多线程的引入

多线程并行和并发的区别

Java程序运行原理和JVM的启动是多线程的吗

//结果中"我是主线程的执行代码"和"垃圾被清除了"是交替出现的
package com.heima.thread;

public class Demo1_Thread {

    /**
     * 证明jvm是多线程的
     */
    public static void main(String[] args) {
        for(int i = 0; i < 100000; i++) {
            new Demo();
        }
        
        for(int i = 0; i < 10000; i++) {
            System.out.println("我是主线程的执行代码");
        }
    }

}

class Demo {

    @Override
    protected void finalize() {
        System.out.println("垃圾被清除了");
    }
    
}

多线程程序实现的方式1

package com.heima.thread;

public class Demo2_Thread {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Mythread mt = new Mythread();       //4,创建Thread类的子类对象
        mt.start();                         //5,开启线程
        for (int i = 0; i < 1000; i++) {    
            System.out.println("bb");
        }
    }

}

class Mythread extends Thread {             //1,继承Thread
    public void run() {                     //2,重写run方法
        for (int i = 0; i < 1000; i++) {    //3,将要执行的代码写在run方法中
            System.out.println("aaaaaa");
        }
    }
}

多线程程序实现的方式2

package com.heima.thread;

public class Demo3_Thread {

    /**
     * @param args
     */
    public static void main(String[] args) {
        MyRunnable mr = new MyRunnable();   //4,创建Runnable的子类对象
        //Runnable target = mr;父类引用指向子类对象
        Thread t = new Thread(mr);  //5,将子类对象传递给Thread的构造函数,父类引用指向子类对象
        t.start();                  //6,开启线程
        
        for (int i = 0; i < 1000; i++) {    
            System.out.println("bb");
        }
    }

}

class MyRunnable implements Runnable {      //1,定义一个类实现Runnable

    @Override
    public void run() {                     //2,重写run方法
        for (int i = 0; i < 1000; i++) {    //3,将要执行的代码写在run方法中
            System.out.println("aaaaaa");
        }
    }
    
}

实现Runnable的原理

两种方式的区别

匿名内部类实现线程的两种方式

package com.heima.thread;

public class Demo4_Thread {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new Thread() {                                  //1,继承Thread类
            public void run() {                         //2,重写run方法
                for (int i = 0; i < 1000; i++) {        //3,将要执行的代码写在run方法中
                    System.out.println("aaaaaaaaa");
                }
            }
        }.start();                                      //4,开启线程
        
        new Thread(new Runnable() {                     //1,将Runnable的子类对象传递给Thread的构造方法
            public void run() {                         //2,重写run方法
                for (int i = 0; i < 1000; i++) {        //3,将要执行的代码写在run方法中
                    System.out.println("bb");
                }
            }
        }).start();                                     //4,开启线程
    }

}

获取名字和设置名字

1.获取名字
* 通过getName()方法获取线程对象的名字

package com.heima.threadmethod;

public class Demo1_Name {

    public static void main(String[] args) {    //通过setName给name(线程名字)赋值
        new Thread("A") {
            public void run() {
                this.setName("张三");
                System.out.println(this.getName() + "....aaa");
            }
        }.start();
        
         Thread t = new Thread("B") {
            public void run() {
                this.setName("李四");
                System.out.println(this.getName() + "....bb");
            }
        };
        //t.setName("李四");
        t.start();
    }

    public static void demo1() {        //通过构造方法给name(线程名字)赋值
        new Thread("A") {
            public void run() {
                System.out.println(this.getName() + "....aaa");
            }
        }.start();
        
        new Thread("B") {
            public void run() {
                System.out.println(this.getName() + "....bbb");
            }
        }.start();
    }

}

获取当前线程的对象

package com.heima.threadmethod;

public class Demo2_CurrentThread {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new Thread() {
            public void run() {
                System.out.println(getName() + "....aaaaaa");
            }
        }.start();
        
        new Thread(new Runnable() {
            public void run() {
                //Thread.currentThread()获取当前正在执行的线程
                System.out.println(Thread.currentThread().getName() + "...bb");
            }   
        }).start();
        
        Thread.currentThread().setName("我是主线程");
        System.out.println(Thread.currentThread().getName());
    }

}

休眠线程

package com.heima.threadmethod;

public class Demo3_Sleep {

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        new Thread() {
            public void run() {
                for(int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                    System.out.println(getName() + "...aaaaa");
                }
            }
        }.start();
        
        new Thread() {
            public void run() {
                for(int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                    System.out.println(getName() + "...bb");
                }
            }
        }.start();
    }

    public static void demo1() throws InterruptedException {
        for(int i = 20;i >= 0; i--) {
            Thread.sleep(1000);     //1秒= 1000毫秒
            System.out.println("倒数第" + i + "秒");
        }
    }

}

守护线程

package com.heima.threadmethod;

public class Demo4_Daemon {

    public static void main(String[] args) {
        Thread t1 = new Thread() {
            public void run() {
                for (int i = 0; i < 2; i++) {
                    System.out.println(getName() + "...aaaaa");
                }
            }
        };
        
        Thread t2 = new Thread() {
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println(getName() + "...bb");
                }
            }
        };
        
        t2.setDaemon(true); //当传入true就是意味着设置为守护线程
        t1.start();
        t2.start();
    }

}

加入线程

package com.heima.threadmethod;

public class Demo5_Join {

    /**
     * @param args
     */
    public static void main(String[] args) {
        final Thread t1 = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(getName() + "...aaaaaaa");
                }
            }
        };
        //匿名内部类在使用它所在方法中的局部变量的时候,必须用final修饰
        Thread t2 = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    if(i == 2) {
                        try {
                            //t1.join();
                            t1.join(1); //插队指定的时间,过了指定时间后,两条线程交替执行,这里是1毫秒
                        } catch (InterruptedException e) {
                            
                            e.printStackTrace();
                        }
                    }
                    System.out.println(getName() + "...bb");
                }
            }
        };
        t1.start();
        t2.start();
    }

}

礼让线程

package com.heima.threadmethod;

public class Demo6_Yield {

    /**
     *
     */
    public static void main(String[] args) {
        new MyThread().start();
        new MyThread().start();
    }

}

class MyThread extends Thread {
    public void run() {
        for(int i = 1;i <= 1000; i++) {
            if(i % 10 == 0) {
                Thread.yield();
            }
            System.out.println(getName() + "..." + i);  //表现出的礼让效果很差
        }
    }
}

设置线程的优先级

package com.heima.threadmethod;

public class Demo7_Priority {

    public static void main(String[] args) {
        Thread t1 = new Thread(){
            public void run() {
                for(int i = 0; i < 1000; i++) {
                    System.out.println(getName() + "...aaaaaaaa");
                }
            }
        };
        
        Thread t2 = new Thread(){
            public void run() {
                for(int i = 0; i < 1000; i++) {
                    System.out.println(getName() + "...bb");
                }
            }
        };
        
        //t1.setPriority(10);       //设置最大优先级
        //t2.setPriority(1);
        
        t1.setPriority(Thread.MIN_PRIORITY);    //设置最小的线程优先级
        t2.setPriority(Thread.MAX_PRIORITY);    //设置最大的线程优先级
        
        t1.start();
        t2.start();
    }

}

同步代码块

package com.heima.syn;

public class Demo1_Synchronized {

    /**
     * @param args
     */
    public static void main(String[] args) {
        final Printer p = new Printer();
        
        new Thread() {
            public void run() {
                while(true) {
                    p.print1();
                }
            }
        }.start();
        
        new Thread() {
            public void run() {
                while(true) {
                    p.print2();
                }
            }
        }.start();
    }

}

class Printer {
    String s = "abc";
    public void print1() {      
        synchronized(s) {
            System.out.print("黑");
            System.out.print("马");
            System.out.print("程");
            System.out.print("序");
            System.out.print("员");
            System.out.println();
        }
    }
    
    public void print2() {
        synchronized(s) {               //同步代码块,锁机制,锁对象可以是任意对象
            System.out.print("传");      //锁对象不能用匿名对象,因为匿名对象不是同一个对象
            System.out.print("智");
            System.out.print("播");
            System.out.print("客");
            System.out.println();
        }
    }
}

同步方法

package com.heima.syn;

public class Demo1_Synchronized {

    /**
     * @param args
     */
    public static void main(String[] args) {
        final Printer2 p = new Printer2();
        
        new Thread() {
            public void run() {
                while(true) {
                    p.print1();
                }
            }
        }.start();
        
        new Thread() {
            public void run() {
                while(true) {
                    p.print2();
                }
            }
        }.start();
    }

}

class Printer2 {
    String s = "abc";
    //public synchronized void print1() {   //同步方法只需要在方法上加synchronized关键字即可
    public static synchronized void print1() {      
        System.out.print("黑");
        System.out.print("马");
        System.out.print("程");
        System.out.print("序");
        System.out.print("员");
        System.out.println();
    }
    
    public void print2() {
        //synchronized(this) {              //非静态的同步方法的锁对象是this
        synchronized(Printer2.class) {      //静态的同步方法的锁对象是该类的字节码        
            System.out.print("传");          
            System.out.print("智");
            System.out.print("播");
            System.out.print("客");
            System.out.println();
        }
    }
}

线程安全问题

package com.heima.syn;

public class Demo3_Ticket {

    /**
     * 需求:铁路售票,一共100张,通过四个窗口卖完
     */
    public static void main(String[] args) {
        new Ticket().start();
        new Ticket().start();
        new Ticket().start();
        new Ticket().start();
    }

}

class Ticket extends Thread {
    private static int ticket = 100;
    
    public void run() {
        while(true) {
            synchronized(Ticket.class) {    //如果用引用数据类型成员变量当作锁对象,必须是静态的
                if(ticket == 0) {
                    break;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    
                    e.printStackTrace();
                }
                System.out.println(getName() + "...这是第" + ticket-- + "号票");
            }
        }
    }
}

火车站卖票的例子用实现Runnable接口

package com.heima.syn;

public class Demo4_Ticket {

    /**
     * @param args
     */
    public static void main(String[] args) {
        MyTicket mt = new MyTicket();
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
        //多次启动一个线程是非法的
    }

}

class MyTicket implements Runnable {
    private int tickets = 100;
    public void run() {
        while(true) {
            synchronized(Ticket.class) {        //这里可以换成this
                if(tickets == 0) {
                    break;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "...这是第" + tickets-- + "号票");
            }
        }
    }
}

死锁

package com.heima.syn;

public class Demo5_DeadLock {

    /**
     * @param args
     */
    private static String s1 = "筷子左";
    private static String s2 = "筷子右";
    public static void main(String[] args) {
        new Thread() {
            public void run() {
                while(true) {
                    synchronized(s1) {
                        System.out.println(getName() + "...获取" + s1 + "等待" + s2);
                        synchronized(s2) {
                            System.out.println(getName() + "...拿到" + s2 + "开吃");
                        }
                    }
                }
            }
        }.start();
        
        new Thread() {
            public void run() {
                while(true) {
                    synchronized(s2) {
                        System.out.println(getName() + "...获取" + s2 + "等待" + s1);
                        synchronized(s1) {
                            System.out.println(getName() + "...拿到" + s1 + "开吃");
                        }
                    }
                }
            }
        }.start();
    }

}

以前的线程安全的类回顾

A:回顾以前说过的线程安全问题
* 看源码:Vector,StringBuffer,Hashtable
Collections.synchroinzed(xxx)返回指定 collection 支持的同步(线程安全的)collection,即可以将线程不安全变成线程安全的
* Vector是线程安全的,ArrayList是线程不安全的
* StringBuffer是线程安全的,StringBuilder是线程不安全的
* Hashtable是线程安全的,HashMap是线程不安全的

单例设计模式

package com.heima.thread;

public class Demo1_Singleton {

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*Singleton s1 = Singleton.s;
        Singleton s2 = Singleton.s;
        System.out.println(s1 == s2);*/
        
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1 == s2);
    }

}

/*
 * 饿汉式
 */
class Singleton {
    //1,私有构造方法,其他类不能访问该构造方法了
    private Singleton() {}
    //2,创建本类对象
    private static Singleton s = new Singleton();
    //3,对外提供公共的访问方法
    public static Singleton getInstance() {         
        return s;
    }
}

/*
 * 懒汉式,单例的延迟加载模式
 */
/*class Singleton {
    //1,私有构造方法,其他类不能访问该构造方法了
    private Singleton() {}
    //2,声明一个引用
    private static Singleton s;
    //3,对外提供公共的访问方法
    public static Singleton getInstance() {
        if(s == null) {
            //多线程会引起创建多个对象
            s = new Singleton();
        }
        return s;
    }
}*/

/*
 * 区别
 * 1,饿汉式是空间换时间,懒汉式是时间换空间
 * 2,在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象
 */
//其他方式
/*class Singleton {
    //1,私有构造方法,其他类不能访问该构造方法了
    private Singleton() {}
    //2,创建本类对象
    public static final Singleton s = new Singleton();

}*/

Runtime类

package com.heima.thread;

import java.io.IOException;

public class Demo2_Runtime {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        Runtime r = Runtime.getRuntime();   //获取运行时对象
        //r.exec("shutdown -s -t 300");//300秒后关机
        r.exec("shutdown -a");//取消关机

    }

}

Timer

package com.heima.thread;


import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Demo3_Timer {

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        Timer t = new Timer();
        //在指定时间安排指定任务
        //第一个参数,是安排的任务,第二个参数是执行的时间,第三个参数是执行的重复周期
        t.schedule(new MyTimerTask(), new Date(118,10,27,9,52,30),3000);
        
        while(true) {
            Thread.sleep(1000);
            System.out.println(new Date());
        }
    }

}

class MyTimerTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("起床被英语单词");
    }
    
}

两个线程间的通信

1.什么时候需要通信
* 多个线程并发执行时, 在默认情况下CPU是随机切换线程的
* 如果我们希望他们有规律的执行, 就可以使用通信, 例如每个线程执行一次打印

package com.heima.thread2;

public class Demo1_Notify {

    /**
     * @param args
     */
    public static void main(String[] args) {
        final Printer p = new Printer();
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print1();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print2();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

}
//等待唤醒机制
class Printer {
    private int flag = 1;
    public void print1() throws InterruptedException {
        synchronized(this) {
            if(flag != 1) {
                this.wait();        //当前线程等待
            }
            System.out.print("黑");
            System.out.print("马");
            System.out.print("程");
            System.out.print("序");
            System.out.print("员");
            System.out.print("\r\n");
            flag = 2;
            this.notify();          //随机唤醒单个等待的线程
        }
    }
    
    public void print2() throws InterruptedException {
        synchronized(this) {
            if(flag != 2) {
                this.wait();
            }
            System.out.print("传");
            System.out.print("智");
            System.out.print("播");
            System.out.print("客");
            System.out.print("\r\n");
            flag = 1;
            this.notify();          
        }
    }
}

三个或三个以上间的线程通信

package com.heima.thread2;

public class Demo2_NotifyAll {

    /**
     * 1,在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法
     * 2,为什么wait方法和notify方法定义在Object这类中?
     *  因为锁对象可以是任意对象,Object是所有类的基类,所以wait方法和notify方法需要定义在Object这个类中
     * 3,sleep方法和wait方法的区别?
     * a,sleep方法必须传入参数,参数就是时间,时间到了自动醒来
     * wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待
     * b,sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡
     * wait方法在同步函数或同步代码块中,释放锁
     */
    public static void main(String[] args) {
        final Printer2 p = new Printer2();
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print1();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print2();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print3();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

}

class Printer2 {
    private int flag = 1;
    public void print1() throws InterruptedException {
        synchronized(this) {
            while(flag != 1) {
                this.wait();        //当前线程等待,if语句是在哪里等待,就在哪里起来
            }                       //while循环是循环判断,每次都会判断标记
            System.out.print("黑");
            System.out.print("马");
            System.out.print("程");
            System.out.print("序");
            System.out.print("员");
            System.out.print("\r\n");
            flag = 2;
            this.notify();          //随机唤醒单个等待的线程
            this.notifyAll();           //随机唤醒单个等待的线程
        }
    }
    
    public void print2() throws InterruptedException {
        synchronized(this) {
            while(flag != 2) {
                this.wait();
            }
            System.out.print("传");
            System.out.print("智");
            System.out.print("播");
            System.out.print("客");
            System.out.print("\r\n");
            flag = 3;
            this.notify();          
            this.notifyAll();           
        }
    }
    
    public void print3() throws InterruptedException {
        synchronized(this) {
            while(flag != 3) {
                this.wait();
            }
            System.out.print("i");
            System.out.print("t");
            System.out.print("g");
            System.out.print("z");
            System.out.print("\r\n");
            flag = 1;
            this.notify();          
            this.notifyAll();           
        }
    }
}

JDK1.5的新特性互斥锁

package com.heima.thread2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Demo3_ReentrantLock {

    /**
     * @param args
     */
    public static void main(String[] args) {
        final Printer3 p = new Printer3();
        
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print1();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print2();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        p.print3();
                    } catch (InterruptedException e) {
                        
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

}

class Printer3 {
    private ReentrantLock r = new ReentrantLock();
    private Condition c1 = r.newCondition();
    private Condition c2 = r.newCondition();
    private Condition c3 = r.newCondition();
    
    private int flag = 1;
    public void print1() throws InterruptedException {
        r.lock();
            if(flag != 1) {
                c1.await();     
            }                       
            System.out.print("黑");
            System.out.print("马");
            System.out.print("程");
            System.out.print("序");
            System.out.print("员");
            System.out.print("\r\n");
            flag = 2;
            c2.signal();
        r.unlock();
    }
    
    public void print2() throws InterruptedException {
        r.lock();
            if(flag != 2) {
                c2.await();
            }
            System.out.print("传");
            System.out.print("智");
            System.out.print("播");
            System.out.print("客");
            System.out.print("\r\n");
            flag = 3;
            c3.signal();            
        r.unlock();
    }
    
    public void print3() throws InterruptedException {
        r.lock();
            if(flag != 3) {
                c3.await();
            }
            System.out.print("i");
            System.out.print("t");
            System.out.print("g");
            System.out.print("z");
            System.out.print("\r\n");
            flag = 1;
            c1.signal();            
        r.unlock();
    }
}

线程组的概述和使用

package com.heima.thread2;

public class Demo4_ThreadGroup {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ThreadGroup tg = new ThreadGroup("我是一个新的线程组");      //创建新的线程组
        MyRunnable mr = new MyRunnable();               //创建Runnable的子类对象
        
        Thread t1 = new Thread(tg, mr, "张三");           //将线程t1放在组中
        Thread t2 = new Thread(tg, mr, "李四");           //将线程t2放在组中
        
        System.out.println(t1.getThreadGroup().getName());  //获取组名
        System.out.println(t2.getThreadGroup().getName());
        
        tg.setDaemon(true);         //将整个组设置为守护线程
    }

    public static void demo1() {
        MyRunnable mr = new MyRunnable();
        Thread t1 = new Thread(mr, "张三");
        Thread t2 = new Thread(mr, "李四");

        ThreadGroup tg1 = t1.getThreadGroup();
        ThreadGroup tg2 = t2.getThreadGroup();

        System.out.println(tg1.getName());      //默认的是主线程
        System.out.println(tg2.getName());
    }

}

class MyRunnable implements Runnable {

    public void run() {
        for(int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread().getName() + "..." + i);
        }
    }
    
}

线程的五种状态

线程状态图.png

线程池的概述和使用

package com.heima.thread2;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo5_Executors {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(2);//创建线程池
        pool.submit(new MyRunnable());                  //将线程放进池子里并执行
        pool.submit(new MyRunnable());
        
        pool.shutdown();                            //关闭线程池
    }

}

多线程程序实现的方式3

package com.heima.thread2;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Demo6_Callable {

    /**
     * @param args
     * @throws ExecutionException 
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool = Executors.newFixedThreadPool(2);//创建线程池
        Future<Integer> f1 = pool.submit(new MyCallable(100));                  //将线程放进池子里并执行
        Future<Integer> f2 = pool.submit(new MyCallable(50));
        
        System.out.println(f1.get());
        System.out.println(f2.get());
        pool.shutdown();                            //关闭线程池
    }

}

class MyCallable implements Callable<Integer> {
    private int num;
    public MyCallable(int num) {
        this.num = num;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= num; i++) {
            sum += i;
        }
        
        return sum;
    }
    
}

简单工厂模式概述和使用

package com.heima.factory;

public abstract class Animal {
    public abstract void eat();
}
package com.heima.factory;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

}
package com.heima.factory;

public class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

}
package com.heima.factory;

public class AnimalFactory {
    public static Animal createAnimal(String name) {
        if("dog".equals(name)) {
            return new Dog();
        }else if("cat".equals(name)) {
            return new Cat();
        }else {
            return null;
        }
    }
}
package com.heima.factory;

public class Test {

    public static void main(String[] args) {
        Dog d = (Dog) AnimalFactory.createAnimal("dog");
        d.eat();
        Cat c = (Cat) AnimalFactory.createAnimal("cat");
        c.eat();
    }

}

工厂方法模式的概述和使用

package com.heima.factorymethod;

public abstract class Animal {
    public abstract void eat();
}
package com.heima.factorymethod;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

}
package com.heima.factorymethod;

public class CatFactory implements Factory {

    @Override
    public Animal createAnimal() {

        return new Cat();
    }


}
package com.heima.factorymethod;

public class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }

}
package com.heima.factorymethod;

public class DogFactory implements Factory {

    @Override
    public Animal createAnimal() {

        return new Dog();
    }

}
package com.heima.factorymethod;

public interface Factory {
    public Animal createAnimal();
}
package com.heima.factorymethod;

public class Test {

    public static void main(String[] args) {
        DogFactory df = new DogFactory();
        Dog d = (Dog) df.createAnimal();
        d.eat();
    }

}

图形界面

package com.heima.gui;

import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class Demo1_Frame {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Frame f = new Frame("我的第一个窗口");
        f.setSize(400, 600);                //设置窗体大小
        f.setLocation(500, 50);             //设置窗体位置
        f.setIconImage(Toolkit.getDefaultToolkit().createImage("qq.png"));
        Button b1 = new Button("按钮一");
        Button b2 = new Button("按钮二");
        f.add(b1);
        f.add(b2);
        f.setLayout(new FlowLayout());      //设置布局管理器
        //f.addWindowListener(new MyWindowAdapter());
        f.addWindowListener(new MyWindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        b1.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {    //单击
                System.exit(0);
            }
            /*public void mouseReleased(MouseEvent e) { //释放
                System.exit(0);
            }*/
        });
        
        b1.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_SPACE) {
                    System.exit(0);
                }
            }
        });
        
        b2.addActionListener(new ActionListener() { //添加动作监听
            
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        f.setVisible(true);                 //设置窗体可见
    }

}

/*class MyWindowListener implements WindowListener {

    @Override
    public void windowOpened(WindowEvent e) {
    }

    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }

    @Override
    public void windowClosed(WindowEvent e) {
        System.out.println("Closed");
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }
    
}*/

class MyWindowAdapter extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
}

适配器设计模式

GUI(需要知道的)

网络编程概述

网络编程三要素之IP概述

网络编程三要素之端口号概述

网络编程三要素协议

Socket通信原理图解

UDP传输

package com.heima.socket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Demo1_Send {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        String str = "what are you doing";
        DatagramSocket socket = new DatagramSocket();   //创建Socket,码头
        DatagramPacket packet =                         //创建Packet,集装箱
                new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
        socket.send(packet);                            //将数据发出去,发货
        socket.close();                                 //关闭Socket,码头
    }

}
package com.heima.socket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Demo1_Receive {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);   //创建Socket相当于创建码头
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);   //创建Packet相当于创建集装箱
        socket.receive(packet);             //接货,接收数据
        
        byte[] arr = packet.getData();      //获取数据
        int len = packet.getLength();       //获取有效字节个数
        System.out.println(new String(arr, 0, len));
        socket.close();
    }

}

UDP传输优化

package com.heima.socket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Demo2_Send {

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        DatagramSocket socket = new DatagramSocket();   //创建Socket,码头
        while(true) {
            String line = sc.nextLine();
            if("quit".equals(line)) {
                break;
            }
            DatagramPacket packet =                         //创建Packet,集装箱
                    new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
            socket.send(packet);                            //将数据发出去,发货
        }
        socket.close();                                 //关闭Socket,码头
    }

}
package com.heima.socket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Demo2_Receive {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);   //创建Socket相当于创建码头
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);   //创建Packet相当于创建集装箱
        while(true) {
            socket.receive(packet);             //接货,接收数据
            
            byte[] arr = packet.getData();      //获取数据
            int len = packet.getLength();       //获取有效字节个数
            String ip = packet.getAddress().getHostAddress();//获取ip地址
            int port = packet.getPort();    //获取端口号
            System.out.println(ip + ":" + port + ":" + new String(arr, 0, len));
        }
    }

}

UDP传输多线程

package com.heima.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Demo3_MoreThread {

    public static void main(String[] args) {
        new Receive().start();
        new Send().start();
    }

}

class Receive extends Thread {
    public void run() {
        try {
            DatagramSocket socket = new DatagramSocket(6666);   //创建Socket相当于创建码头
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);   //创建Packet相当于创建集装箱
            while(true) {
                socket.receive(packet);             //接货,接收数据
                
                byte[] arr = packet.getData();      //获取数据
                int len = packet.getLength();       //获取有效字节个数
                String ip = packet.getAddress().getHostAddress();//获取ip地址
                int port = packet.getPort();    //获取端口号
                System.out.println(ip + ":" + port + ":" + new String(arr, 0, len));
            }
        }  catch (IOException e) {      
            e.printStackTrace();
        }
    }
}

class Send extends Thread {
    public void run() {
        try {
            Scanner sc = new Scanner(System.in);
            DatagramSocket socket = new DatagramSocket();   //创建Socket,码头
            while(true) {
                String line = sc.nextLine();
                if("quit".equals(line)) {
                    break;
                }
                DatagramPacket packet =                         //创建Packet,集装箱
                        new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
                socket.send(packet);                            //将数据发出去,发货
            }
            socket.close();
        } catch (IOException e) {
            
            e.printStackTrace();
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读