Java-多线程编程(一)

创建多线程

【Thread class】1.继承Thread类,重写run()

【Runnable接口】2.实现Runnable接口,重写run()

【*Callable接口】3.实现Callable接口——高级并发编程JUC

根据面向对象思想,少用继承,多用实现,因为Java有单继承的局限性:继承了Thread类,不得不继承其他类,就不得不重构代码。

* 执行线程必须调用start()加入到调度器中

* 不一定立即执行,系统安排调度分配执行

* 直接调用run()不是开启多线程,是普通方法调用

package com.zrl.thread;
/**
 * 创建线程方式一
 * 1.创建:继承Thread+重写run
 * 2.启动:创建子类对象+start
 * @author 16114
 *
 */

public class StartThread extends Thread{
    /**
     * 线程入口点
     */
    public void run() {
        for(int i=0; i<5; i++) {
            System.out.println("一边听歌");
        }
    }
    
    public static void main(String[] args) {
        //创建子类对象
        StartThread st = new StartThread();
        //启动
        st.start();//不保证立刻运行 cpu调用
        //st.run();//普通方法的调用
        for(int i=0; i<5; i++) {
            System.out.println("一边Coding");
        }
    }

}
package com.zrl.thread;
/**
 * 创建线程方式二
 * 1.创建:实现Runnable接口+重写run
 * 2.启动:实现对象+Thread代理+start
 * @author 16114
 *
 */

public class StartThread implements Runnable{
    /**
     * 线程入口点
     */
    public void run() {
        for(int i=0; i<5; i++) {
            System.out.println("一边听歌");
        }
    }
    
    public static void main(String[] args) {
        //创建子类对象
        //StartThread s = new StartThread();
        //启动
        //Thread st = new Thread(s);
        //st.start();//不保证立刻运行 cpu调用
        //st.run();//普通方法的调用
        //匿名:类只使用一次
        new Thread(new StartThread()).start();;
        for(int i=0; i<5; i++) {
            System.out.println("一边Coding");
        }
    }

}

使用线程模拟龟兔赛跑

package com.zrl.thread;
/**
 * 模拟龟兔赛跑
 * @author 16114
 *
 */
public class Racer implements Runnable{
    private static String winner; //胜利者
    @Override
    public void run() {
        for(int step=1;step<=100;step++) {
            //模拟兔子休息
            if(step%10==0 && Thread.currentThread().getName().equals("rabbit")) {{
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
              }
            }
            System.out.println(Thread.currentThread().getName()+"-->"+step);
            boolean flag = gameOver(step);
            if(flag) {
                break;
            }
        }
    }
    private boolean gameOver(int step) {
        if(winner != null) { //没有胜利者
            return true;
        }
        else {
            if(step == 100) {
                winner = Thread.currentThread().getName();
                System.out.println("winner ==> " + winner);
                return true;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        Racer r = new Racer();
        new Thread(r,"tortoise").start();
        new Thread(r,"rabbit").start();
        
    }

}

静态代理类

package com.zrl.thread;

public class StaticProxy {
    public static void main(String[] args) {
        new WeddingCompany(new You()).happyMarry();
        //new Thread(线程对象).start();
    }
}
interface Marry{
    void happyMarry();
}
class You implements Marry{
    @Override
    public void happyMarry() {
        System.out.println("you and 嫦娥终于奔月...");
    }
}
//代理角色
class WeddingCompany implements Marry{
    //真实角色
    private Marry target;
    public WeddingCompany(Marry target) {
        this.target = target;
    }
    @Override
    public void happyMarry() {
        ready();
        this.target.happyMarry();
        after();
    }
    private void ready() {
        System.out.println("布置猪窝...");
    }
    private void after() {
        System.out.println("闹玉兔...");
    }
}

lambda(jdk8新特性)

外部类——>静态内部类 ——>匿名内部类 ——>方法内部类

线程状态

看成足球比赛,每个线程当成球员。

新生状态 :入选23人大名单

就绪状态  :安排入场

运行状态:带球奔跑

阻塞状态:受到对方干扰(不是马上奔跑,从奔跑切换到就绪状态)

死亡状态:替换下场

如何切换到就绪状态

1.start()

2.解除阻塞状态

3.yield

4.jvm本身将CPU本地线程切换到其他线程

运行状态一定被CPU调度到了,不会从阻塞状态转到运行状态

 

如何切换到阻塞状态

1.sleep()延时,抱着资源不给别人

2.wait,红绿灯

3.join,插队

4.IO操作,read、write

原文地址:https://www.cnblogs.com/Roni-i/p/9733601.html