百木园-与人分享,
就是让自己快乐。

多线程(多线程实现方式一【继承类Thread类】)

多线程方式实现(1)

方式1:继承Thread类。
* 步骤
* A:自定义类MyThread继承Thread类。
* B:MyThread类里面重写run()?
* 为什么是run()方法呢?
* C:创建对象
* D:启动线程
*/

package cn.itcast_02;

/*
 * 该类要重写run()方法,为什么呢?
 * 不是类中的所有代码都需要被线程执行的。
 * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。
 */
public class MyThread extends Thread {

    @Override
    public void run() {
        // 自己写代码
        // System.out.println(\"好好学习,天天向上\");
        // 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进
        for (int x = 0; x < 200; x++) {
            System.out.println(x);
        }
    }

}
package cn.itcast_02;

/*
 * 需求:我们要实现多线程的程序。
 * 如何实现呢?
 *         由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来。
 *         而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。
 *         Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。
 *         但是呢?Java可以去调用C/C++写好的程序来实现多线程程序。
 *         由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,
 *         然后提供一些类供我们使用。我们就可以实现多线程程序了。
 * 那么Java提供的类是什么呢?
 *         Thread
 *         通过查看API,我们知道了有2中方式实现多线程程序。
 * 
 * 方式1:继承Thread类。
 * 步骤
 *         A:自定义类MyThread继承Thread类。
 *         B:MyThread类里面重写run()?
 *             为什么是run()方法呢?
 *         C:创建对象
 *         D:启动线程
 */
public class MyThreadDemo {
    public static void main(String[] args) {
        // 创建线程对象
        // MyThread my = new MyThread();
        // // 启动线程
        // my.run();
        // my.run();
        // 调用run()方法为什么是单线程的呢?
        // 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果
        // 要想看到多线程的效果,就必须说说另一个方法:start()
        // 面试题:run()和start()的区别?
        // run():仅仅是封装被线程执行的代码,直接调用是普通方法
        // start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
        // MyThread my = new MyThread();
        // my.start();
        // // IllegalThreadStateException:非法的线程状态异常
        // // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。
        // my.start();

        // 创建两个线程对象
        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();

        my1.start();
        my2.start();
    }
}

 获取和设置线程对象名称

//我要获取main方法所在的线程对象的名称,该怎么办呢?
        //遇到这种情况,Thread类提供了一个很好玩的方法:
        //public static Thread currentThread():返回当前正在执行的线程对象
        System.out.println(Thread.currentThread().getName());
package cn.itcast_03;

public class MyThread extends Thread {

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

    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            System.out.println(getName() + \":\" + x);
        }
    }
}
package cn.itcast_03;

/*
 * 如何获取线程对象的名称呢?
 * public final String getName():获取线程的名称。
 * 如何设置线程对象的名称呢?
 * public final void setName(String name):设置线程的名称
 * 
 * 针对不是Thread类的子类中如何获取线程对象名称呢?
 * public static Thread currentThread():返回当前正在执行的线程对象
 * Thread.currentThread().getName()
 */
public class MyThreadDemo {
    public static void main(String[] args) {
        // 创建线程对象
        //无参构造+setXxx()
        // MyThread my1 = new MyThread();
        // MyThread my2 = new MyThread();
        // //调用方法设置名称
        // my1.setName(\"林青霞\");
        // my2.setName(\"刘意\");
        // my1.start();
        // my2.start();
        
        //带参构造方法给线程起名字
        // MyThread my1 = new MyThread(\"林青霞\");
        // MyThread my2 = new MyThread(\"刘意\");
        // my1.start();
        // my2.start();
        
        //我要获取main方法所在的线程对象的名称,该怎么办呢?
        //遇到这种情况,Thread类提供了一个很好玩的方法:
        //public static Thread currentThread():返回当前正在执行的线程对象
        System.out.println(Thread.currentThread().getName());
    }
}

/*
名称为什么是:Thread-? 编号

class Thread {
    private char name[];

    public Thread() {
        init(null, null, \"Thread-\" + nextThreadNum(), 0);
    }
    
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null);
    }
    
     private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
        //大部分代码被省略了
        this.name = name.toCharArray();
    }
    
    public final void setName(String name) {
        this.name = name.toCharArray();
    }
    
    
    private static int threadInitNumber; //0,1,2
    private static synchronized int nextThreadNum() {
        return threadInitNumber++; //return 0,1
    }
    
    public final String getName() {
        return String.valueOf(name);
    }
}

class MyThread extends Thread {
    public MyThread() {
        super();
    }
}

*/

 

线程调度及获取和设置线程优先级

package cn.itcast_04;

public class ThreadPriority extends Thread {
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            System.out.println(getName() + \":\" + x);
        }
    }
}
package cn.itcast_04;

/*
 * 我们的线程没有设置优先级,肯定有默认优先级。
 * 那么,默认优先级是多少呢?
 * 如何获取线程对象的优先级?
 *         public final int getPriority():返回线程对象的优先级
 * 如何设置线程对象的优先级呢?
 *         public final void setPriority(int newPriority):更改线程的优先级。 
 * 
 * 注意:
 *         线程默认优先级是5。
 *         线程优先级的范围是:1-10。
 *         线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。
 *         
 * IllegalArgumentException:非法参数异常。
 * 抛出的异常表明向方法传递了一个不合法或不正确的参数。 
 * 
 */
public class ThreadPriorityDemo {
    public static void main(String[] args) {
        ThreadPriority tp1 = new ThreadPriority();
        ThreadPriority tp2 = new ThreadPriority();
        ThreadPriority tp3 = new ThreadPriority();

        tp1.setName(\"东方不败\");
        tp2.setName(\"岳不群\");
        tp3.setName(\"林平之\");

        // 获取默认优先级
        // System.out.println(tp1.getPriority());
        // System.out.println(tp2.getPriority());
        // System.out.println(tp3.getPriority());

        // 设置线程优先级
        // tp1.setPriority(100000);
        
        //设置正确的线程优先级
        tp1.setPriority(10);
        tp2.setPriority(1);

        tp1.start();
        tp2.start();
        tp3.start();
    }
}

 

练习版

package Day23;
/*
*      * 方式1:继承Thread类。
 * 步骤
 *         A:自定义类MyThread继承Thread类。
 *         B:MyThread类里面重写run()?
 *             为什么是run()方法呢?
 *         C:创建对象
 *         D:启动线程
 */
public class ThreadDemo {
    public static void main(String[] args) {
        //创建对象
        MyThreadDemo myd  = new MyThreadDemo();
        MyThreadDemo myd1  = new MyThreadDemo();
        MyThreadDemo myd2 = new MyThreadDemo();
        //启动线程
        //public void start()使该线程开始执行;Java 虚拟机调用该线程的 run 方法
        //结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。

        //设置该线程对象的名称
        myd.setName(\"刘备\");
        myd1.setName(\"关羽\");
        myd2.setName(\"张飞\");

        //设置线程执行优先级
        //public final void setPriority(int newPriority)更改线程的优先级。
        //参数:newPriority - 要为线程设定的优先级
        myd.setPriority(1);
        myd1.setPriority(10);
        myd2.setPriority(5);
        

//        //创建对象的同时设置线程名称----
//        MyThreadDemo myd2 = new MyThreadDemo(\"长江\");
//        MyThreadDemo myd3 = new MyThreadDemo(\"黄河\");

       //运行调用-----输出查看
        myd.start();
        myd1.start();
        myd2.start();


    }
}

 线程控制之线程休眠

package cn.itcast_04;

import java.util.Date;

public class ThreadSleep extends Thread {
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            System.out.println(getName() + \":\" + x + \",日期:\" + new Date());
            // 睡眠
            // 困了,我稍微休息1秒钟
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package cn.itcast_04;

/*
 * 线程休眠
 *        public static void sleep(long millis)
 */
public class ThreadSleepDemo {
    public static void main(String[] args) {
        ThreadSleep ts1 = new ThreadSleep();
        ThreadSleep ts2 = new ThreadSleep();
        ThreadSleep ts3 = new ThreadSleep();

        ts1.setName(\"林青霞\");
        ts2.setName(\"林志玲\");
        ts3.setName(\"林志颖\");

        ts1.start();
        ts2.start();
        ts3.start();
    }
}

 

 线程控制之线程之加入线程

package Day23;
//创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。
// 该子类应重写 Thread 类的 run 方法。
public class ThreadDemo1 extends Thread {
    //重写Thread中的run方法
    @Override
    public void run() {
       for(int x=0;x<100;x++){
           //获取线程对象的名称
           System.out.println(getName()+\":\"+x);
       }
    }
}
package Day23;

import com.sun.org.apache.bcel.internal.generic.NEW;

//线程控制之加入线程
//public final void join()
// throws InterruptedException等待该线程终止。----该线程终止后再运行其他的
public class join {
    public static void main(String[] args) throws InterruptedException {
        //创建ThreadDemo1对象
        ThreadDemo1 TD = new ThreadDemo1();
        ThreadDemo1 TD1 = new ThreadDemo1();
        ThreadDemo1 TD2 = new ThreadDemo1();

        //设置线程对象名称
        //public final void setName(String name)改变线程名称,使之与参数 name 相同。
        TD.setName(\"刘备\");
        TD1.setName(\"关羽\");
        TD2.setName(\"张飞\");

        //执行线程
        TD.start();
        //首先执行此线程---此线程执行完毕后再执行其他线程
        //public final void join()
        //throws InterruptedException等待该线程终止
        TD.join();


        TD1.start();
        TD2.start();


    }
}

 

 线程控制之线程礼让

public static void yield()
暂停当前正在执行的线程对象,并执行其他线程。 
package cn.itcast_04;

public class ThreadYield extends Thread {
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            System.out.println(getName() + \":\" + x);
            Thread.yield();
        }
    }
}

 

package cn.itcast_04;

/*
 * public static void yield():暂停当前正在执行的线程对象,并执行其他线程。 
 * 让多个线程的执行更和谐,但是不能靠它保证一人一次。
 */
public class ThreadYieldDemo {
    public static void main(String[] args) {
        ThreadYield ty1 = new ThreadYield();
        ThreadYield ty2 = new ThreadYield();

        ty1.setName(\"林青霞\");
        ty2.setName(\"刘意\");

        ty1.start();
        ty2.start();
    }
}

 

 线程控制之守护线程

package cn.itcast_04;

public class ThreadDaemon extends Thread {
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
            System.out.println(getName() + \":\" + x);
        }
    }
}
package cn.itcast_04;

/*
 * public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
 * 当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。 
 * 
 * 游戏:坦克大战。
 */
public class ThreadDaemonDemo {
    public static void main(String[] args) {
        ThreadDaemon td1 = new ThreadDaemon();
        ThreadDaemon td2 = new ThreadDaemon();

        td1.setName(\"关羽\");
        td2.setName(\"张飞\");

        // 设置守护线程
        td1.setDaemon(true);
        td2.setDaemon(true);

        td1.start();
        td2.start();
        //主线程---主线程结束--守护线程也会随之停止
        Thread.currentThread().setName(\"刘备\");
        for (int x = 0; x < 5; x++) {
            System.out.println(Thread.currentThread().getName() + \":\" + x);
        }
    }
}

 

线程控制之中断线程

public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException

package cn.itcast_04;

import java.util.Date;

public class ThreadStop extends Thread {
    @Override
    public void run() {
        System.out.println(\"开始执行:\" + new Date());

        // 我要休息10秒钟,亲,不要打扰我哦
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // e.printStackTrace();
            System.out.println(\"线程被终止了\");
        }

        System.out.println(\"结束执行:\" + new Date());
    }
}

 

package cn.itcast_04;

/*
 * public final void stop():让线程停止,过时了,但是还可以使用。
 * public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。
 */
public class ThreadStopDemo {
    public static void main(String[] args) {
        ThreadStop ts = new ThreadStop();
        ts.start();

        // 你超过三秒不醒过来,我就干死你
        try {
            Thread.sleep(3000);
            // ts.stop();
            ts.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 


来源:https://www.cnblogs.com/ztg-java-xuexi/p/16100662.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 多线程(多线程实现方式一【继承类Thread类】)

相关推荐

  • 暂无文章