Java线程创建(卖票),线程同步(卖包子)的实现示例

1.线程两种创建方式:new Thread(new Runnable() {})

如下FileOutputStream源码中抛出异常,为了让写代码人自己写try catch异常提示信息。

package com.itheim07.thread;
/*
*   进程和线程
*       1. 进程 :  航空母舰(资源: 燃油 弹药)
*       2. 线程 :  舰载机
*     一个软件运行: 一个军事活动, 必须有一艘航母出去,但执行具体任务的是航母上的舰载机
*     一个软件运行,至少一个进程, 一个进程中至少一个线程。谷歌浏览器是多进程,进程多了,占用资源多,速度快
*
*   cpu: 4核 8线程。线程要运行,需要cpu授予执行权(指挥室),指挥室可以同时调度8架 飞机
*       1. 并行 : 同一时间,同时执行 (并行只能8线程)
*       2. 并发 : 同一段时间, 实际上是交替执行, 速度快的时候看起来像是同时执行(频率快)(常见: 并发1800线程)
*
*   cpu调度算法(并发)
*       1. 分时调度 : 1800s, 每个线程1s
*       2. 抢占式调度 : 按照线程优先级进行分配, 优先级高(可以自己设置)一般就分配的多(随机性强) java
*
*   为什么需要多线程?
*       1. 默认java代码有两个线程
*           1. main方法线程 : 主线程
*           2. GC线程(jvm使用的,我们无法调度)
*       2. 一个线程可用, 有什么局限性?只能做一件事
*       3. 如果想要同时执行多个任务 -> 多线程
*/
public class ThreadDemo {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("播放音乐...");
                }
            }
        }).start();  //.start()不能改成.run()

        boolean result = true;
        while(result){
            System.out.println("下载电影...");
        }
       /* while(result){ //虽然骗了编译器,但还是不能执行到这里
            System.out.println("播放音乐...");
        }*/
    }
}

如下线程第一种创建方式。

package com.itheima01.thread;
/*
    Thread:1. start() : 启动线程,jvm会创建线程,并调用run方法
            2. static Thread currentThread(),返回对当前正在执行的线程对象的引用。
            3. String getName() : 获取线程名称
     !!! Thread.currentThread().getName() : 获取当前线程名称

      线程默认命名规则:1. main线程 :  main
         2. 子线程(main线程创建的线程) : static int number;static被共享
            Thread-0 , 1, 2 ...
*/
public class ThreadDemo02 {
    public static void main(String[] args) {
//        Thread thread = Thread.currentThread();
//        String name = thread.getName();
//        System.out.println(name); // main
        //下面一行等同于上面
        System.out.println("主:" + Thread.currentThread().getName());

        YourThread yt = new YourThread();
        yt.start(); //子:Thread-0
        YourThread yt2 = new YourThread();
		yt.run(); //子:main。  因为子线程YourThread还未执行起飞	,被main飞机拖着走
        YourThread yt3 = new YourThread();
        yt3.start(); //子:Thread-2。  不是Thread-1是因为yt2未起飞但依旧new了yt2

//        Person p = new Person(); //执行空参构造
//        System.out.println(p.number); //0
//        Person p2 = new Person();
//        System.out.println(p2.number); //1
    }
}
class YourThread extends Thread{
    @Override
    public void run() {
        System.out.println("子:" + Thread.currentThread().getName());
    }
}
class Person{
    static int number=-1;
    public Person(){
        number++;
    }
}
package com.itheima02.runnable;
/*
* 线程第二种创建方式: 1. 声明实现 Runnable 接口的类。
*      				  2. 该类然后实现 run 方法。
*       			  3. 然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。
*      					Thread(Runnable target)
*/
public class RunnableDemo {
    public static void main(String[] args) {
        MyRunnable mr = new MyRunnable(); // 分配该类的实例
        Thread t = new Thread(mr);
        t.start();  //Thread-0
    }
}
class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
package com.itheima02.runnable;
//用匿名内部类简化上面代码
public class RunnableDemo02 {
    public static void main(String[] args) {
     /* Runnable mr = new Runnable(){ //用接口名Runnable代替子类类名,匿名对象。
  //不用再写class MyRunnable implements Runnable{},Runnable mr = new MyRunable(); 向上转型
            @Override
            public void run() {  //new一个接口()再{},是new这个接口的子类对象
                System.out.println(Thread.currentThread().getName());
            }
        };

        Thread t = new Thread(mr);
        t.start();
	   // new Thread(mr).start(); */

//111111111111111111111111111111111111111111111111111111111111111111111111111111
       new Thread(new Runnable() {
           @Override
           public void run() { //主要关注run
               System.out.println(Thread.currentThread().getName());
           }
       }).start();

//new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
    }
}

2.卖票:原子性

package com.itheima03.ticket;
/*
*  需求假设某航空公司有三个窗口发售某日某次航班的100张票,100张票可以作为共享资源,三个售票窗口需要创建三个线程
*  	    好处: 多线程执行同一任务,比较快
*  	        1. 程序(单线程) , 并发1600线程, cpu分配执行权: 1/1600
*  	        2. 程序(多线程 100)  , 并发1700, cpu分配给我们的程序执行权更多:1/17
*  	    注意: 线程不是越多越好(线程本身很占内存, 慢。票数不多不需要用多线程)
*/
public class TicketDemo01 {
    public static void main(String[] args) {
        MyWindow mw1 = new MyWindow(); //堆中开一块空间,不加static,number=100进堆
        mw1.setName("窗口壹");

        MyWindow mw2 = new MyWindow(); //同上
        mw2.setName("窗口222");

        MyWindow mw3 = new MyWindow(); //同上
        mw3.setName("窗口三三三");
        mw1.start();
        mw2.start();
        mw3.start();
    }
}

//11111111111111111111111111111111111111111111111111111111111111111111111111111
class MyWindow extends Thread{
    static int number = 100; //去掉static,每创建一个MyWindow窗口在堆里开辟一块空间,三个窗口各卖100张
    @Override
    public void run() {
       while(number > 0){
           System.out.println(Thread.currentThread().getName() + "正在卖出第" + number + "张票");
           number--;
       }
    }
}
/*
*   两种线程创建方式: 1. 继承Thread
*       			  2. 实现Runnbale
*   如上第二种方案会更好一些,不需要加static,因为只new了一个对象
*       1. 实现接口,而不是继承类(扩展性更强) 接口可以多实现,但是类只能单继承(MyWindow继承Thread后,就不能继承另外的类。MyTask可以继承其他类,实现其他接口)
*       2. 更符合 面向对象 (高内聚,低耦合:线程独立,和业务代码MyTask分离,传入卖猪肉任务也行)。封装(各干各的,有必要再进行合作)
*/

如下线程同步问题分析:两种创建方式3个窗口都总卖出102张票,而不是100张。原因:三个窗口同时卡在打印正在卖出第100张票。解决:t1在卖第100张票时,cpu可能会切到t3和t2,可以控制t2和t3不动,等t1的number- -完再动。

3.线程同步:synchronized关键字,Lock接口,ThreadLocal

package com.itheima04.synchronizedd;
import java.io.IOException;
/*
*       1. 代码块
*           synchronized(锁对象){
*               代码A
*           }
*           1. 锁对象可以是任意对象,但必须唯一
*           2. 同步代码块中的 代码A 同一时间,只允许一个线程执行
* 使用同步锁的注意点:1. 在保证业务逻辑可用的情况,同步锁加的范围越小越好
*
*  2. 锁对象必须唯一:<1> 如果能保证当前对象唯一,this也可以作为锁对象 (更节省内存)
*  <2> 当前类名.class(最好的锁对象) -> Class对象(一个类被加载,在内存都会有一个Class对象) 反射
*/
public class TicketDemo02 {
    public static void main(String[] args) {
        MyTask mt = new MyTask();
        //上面只new了一个,可以用this
        Thread t1 = new Thread(mt);
        t1.setName("窗口壹");

        Thread t2 = new Thread(mt);
        t2.setName("窗口222");

        Thread t3 = new Thread(mt);
        t3.setName("窗口三三三");
        t1.start();
        t2.start();
        t3.start();
    }
}

class MyTask implements Runnable{
    int number = 100;
//   Object obj = new Object();  //锁对象
    @Override
    public void run() {
        while(number > 0){

//1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
            synchronized(MyTask.class){ //MyTask.class也可以换成this
                if(number <= 0){
                    break;  //跳出while大循环
                }
                System.out.println(Thread.currentThread().getName() + "正在卖出第" + number + "张票");
                number--;
            }  

//111111111111111111111111111111111111111111111111111111111111111111111111111111111111
//这边只能try catch不能throws,原因:父类Runnable中run方法没有声明抛出编译异常,所以子类也不能throws
            try {
                Thread.sleep(1); //线程啥事也不干,暂停1ms,cpu有空闲切换其他线程
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } //while里
    }
}

如下t2卖到0张时出while,而t1和t3还在while里,此时number=0,所以变为0和-1。

如下把synchronized拖到外面也不行。

如下加if(number <= 0),没有加浪费时间代码,所以看不到交替效果,但不会出现0和-1。

obj是锁对象即钥匙,如下钥匙不能进run方法(每个线程一把即三把钥匙了),只能在成员位置。

用this,不用new object(),可以节约内存。

package com.itheima05.method;
/*
*   synchronized 方法(同步方法)
*         1. 语法 :  方法声明 + synchronized
*         2. 同步方法有没有锁对象? 有
*               1. 普通方法: 是this
*               2. 静态方法: 静态不能和对象(this)有关。 是当前类名.class
*/
public class TicketDemo02 {
    public static void main(String[] args) {
        MyTask mt = new MyTask();
        Thread t1 = new Thread(mt);
        t1.setName("窗口壹");

        Thread t2 = new Thread(mt);
        t2.setName("窗口222");

        Thread t3 = new Thread(mt);
        t3.setName("窗口三三三");
        t1.start();
        t2.start();
        t3.start();
    }
}

class MyTask implements Runnable{
    static int number = 100;
    @Override
    public void run() {
        while(number > 0){
            method(); //非静态方法可以调用静态方法
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static synchronized void method() { //静态方法不能和对象关键字如this相关  //同步方法效果  等价于 同步代码块
        if(number <= 0){
            return;  //break只能写在循环和switch里
        }
        System.out.println(Thread.currentThread().getName() + "正在卖出第" + number + "张票");
        number--;
    }
}
package com.itheima06.lock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
*   Lock接口: 1. 实现类 ReentrantLock
*             2. lock() 获取锁(获取钥匙)
*             3. unlock() 释放锁 (还钥匙)
*/
public class TicketDemo02 {
    public static void main(String[] args) {
        MyTask mt = new MyTask();
        Thread t1 = new Thread(mt);
        t1.setName("窗口壹");

        Thread t2 = new Thread(mt);
        t2.setName("窗口222");

        Thread t3 = new Thread(mt);
        t3.setName("窗口三三三");
        t1.start();
        t2.start();
        t3.start();
    }
}

class MyTask implements Runnable{
    int number = 100;
    Lock lock = new ReentrantLock(); //创建lock对象
    @Override
    public void run() {
        while(number > 0){

//1111111111111111111111111111111111111111111111111111111111111111111111111
            lock.lock();
            if(number <= 0){
//                System.out.println(Thread.currentThread().getName());
                lock.unlock(); // 注意: lock提供了锁的可视化操作(线程执行结束,要记得手动释放。厕所上完不能带走钥匙)//同步代码块return或break后是jvm自动释放锁。//这里不加lock.unlock()程序停不下来。
                break;
            }
            System.out.println(Thread.currentThread().getName() + "正在卖出第" + number + "张票");
            number--;
            lock.unlock();
        }
    }
}

如下ThreadLocal相当于一个map,key就是当前的线程,value就是需要存储的对象。

t1(…,User),如下情况可将User放入ThreadLocal中,每次通过.get拿到线程的User。

4.卖包子:wait,notify

package com.itheima07.bz;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();
// obj.wait(); //IllegalMonitorStateException : 非法的监视状态异常,因为.wait()必须锁对象调用如下
        synchronized (obj){  //对象变成锁对象
            obj.wait(); //不会报错,一直等待。在锁对象中
        }
    }
}

如下两个方法wait和notify不是给线程调用的,而是给锁对象【锁对象可以是任意对象】调用的如上所示。BaoZi只能一个线程对其操作。

package com.itheima07.bz;

public class BaoZi {
    boolean isHave=false; //默认没有包子
}
package com.itheima07.bz;

public class BaoziPu extends Thread {
    BaoZi bz;
    public BaoziPu(BaoZi bz){
        this.bz = bz;
    }
    @Override
    public void run() {
        while(true){ //不停生产包子 

//111111111111111111111111111111111111111111111111111111111111111111111111111111
            synchronized (bz){ //加锁: 同步代码,生产包子时不让别人打扰我。注意下面wait和notify
                if(bz.isHave){
                    try {
                        bz.wait(); //包子铺有包子就等待(此时吃货正在吃包子)
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("包子铺生产包子..."); //没包子
                bz.isHave = true;
                bz.notify(); //唤醒吃货
            }
        }  //while里
    }
}
package com.itheima07.bz;

public class ChiHuo  extends Thread{
    BaoZi bz;
    public ChiHuo(BaoZi bz){
        this.bz = bz;
    }
    @Override
    public void run() {
        while(true){ //不停吃包子

//1111111111111111111111111111111111111111111111111111111111111111111111111111
            synchronized (bz){
                if(!bz.isHave){
                    try {
                        bz.wait(); //吃货没有包子就等待(此时包子铺正在生产包子)
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("吃货吃包子"); //有包子
                bz.isHave = false;
                bz.notify(); //唤醒包子铺
            }
        }
    }
}
package com.itheima07.bz;

public class BzDemo {
    public static void main(String[] args) {
        BaoZi bz = new BaoZi();
        BaoziPu bzp = new BaoziPu(bz); //和下面一行共同操作一个包子对象
        ChiHuo ch = new ChiHuo(bz);
        bzp.start();
        ch.start();
    }
}

如下第一次没有包子,所以绕过2中if到1。运行完1后就有包子了,1时间很短,cpu不切换线程,切换了也没用,因为2中syn…(bz)包子被锁住,就算切换到吃货线程进不去syn…(bz)里,所以1中notify唤不醒吃货线程。

1和2都在sy…(bz)里,bzp线程bz.wait()【有3个好处】进入等待状态即进入监视队列即等待包子被吃,吃货线程的synchronized锁被打开,有包子不会wait,执行3。

一个线程wait把自己停下来放入堆(监视队列)中,来年开春,另一个线程中3叫我起来干活。2和3对应,1和4对应。3唤醒了2中wait,但2没钥匙(锁)动不了(鬼压床),钥匙在吃货手上,所以3往后4执行释放锁,1234不停循环执行。

生产消费者模型:用户发请求来相当于包子铺生产包子即生产者服务器24小时开着相当于消费者一天24小时等包子吃。不会让消费者线程空转浪费cpu资源,所以没包子设置消费者线程为wait状态不占用cpu资源

package com.atguigu.test14;
// 线程通信是用来解决生产者与消费者问题。
public class Test14 {
	public static void main(String[] args) {
		Workbench tai = new Workbench(); //相当于包子
		Cook c = new Cook("崔志恒", tai); //生产者
		Waiter w = new Waiter("翠花", tai);	//消费者
		c.start();
		w.start();
	}
}

//11111111111111111111111111111111111111111111111111111111111111111111111111
class Workbench{
	private static final int MAX = 10; //假设工作台上最多能够放10盘
	private int count; //count是共用的,要考虑线程安全	

	public synchronized void put(){ //同步方法,非静态方法来说,锁对象就是this //往工作台上放一盘菜
		if(count >= MAX){
			try {
				//生产者停下来,等待
				wait();//默认是this.wait(),所以上面必须加锁对象synchronized
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//上面是安全校验
		count++;
		System.out.println(Thread.currentThread().getName() + "放了一盘菜,剩余:" + count);
		this.notify(); // 包子/工作台.notify()  //唤醒消费者
	}	

//1111111111111111111111111111111111111111111111111111111111111111111111111111
	public synchronized void take(){//从工作台上取走一盘菜
		if(count<=0){
			try {
				wait(); //工作台没有菜,消费者应该停下来
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//上面是安全校验
		count--;
		System.out.println(Thread.currentThread().getName() + "取走一盘菜,剩余:" + count);
		this.notify();  //唤醒生产者
	}
}

//1111111111111111111111111111111111111111111111111111111111111111111111111
class Cook extends Thread{
	private Workbench tai;
	public Cook(String name, Workbench tai) {
		super(name);
		this.tai = tai;
	}
	public void run(){
		while(true){
			tai.put(); //封装了
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

//111111111111111111111111111111111111111111111111111111111111111111111
class Waiter extends Thread{
	private Workbench tai;
	public Waiter(String name, Workbench tai) {
		super(name); //name属性在父类中已声明
		this.tai = tai;
	}
	public void run(){
		while(true){
			tai.take();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

如下一直交替运行,不停。

如下线程6态:锁就是钥匙上厕所,限时等待就是sleep,记住下面三个红色。

如下B进不去不执行

到此这篇关于Java线程创建(卖票),线程同步(卖包子)的实现示例的文章就介绍到这了,更多相关Java线程创建同步内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-05-04

java多线程编程之使用runnable接口创建线程

1.将实现Runnable接口的类实例化. 2.建立一个Thread对象,并将第一步实例化后的对象作为参数传入Thread类的构造方法. 最后通过Thread类的start方法建立线程.下面的代码演示了如何使用Runnable接口来创建线程: package mythread;public class MyRunnable implements Runnable{ public void run() {  System.out.println(Thread.currentThread().get

java多线程编程之使用thread类创建线程

在Java中创建线程有两种方法:使用Thread类和使用Runnable接口.在使用Runnable接口时需要建立一个Thread实例.因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例.Thread类的构造方法被重载了八次,构造方法如下: 复制代码 代码如下: public Thread( );public Thread(Runnable target);public Thread(String name);public Thread(Ru

Java创建多线程的两种方式对比

采用继承Thead类实现多线程: 优势:编写简单,如果需要访问当前线程,只需使用this即可,无需使用Thead.currentThread()方法. 劣势:因为这种线程类已经继承了Thead类,所以不能再继承其它类. 示例代码: 复制代码 代码如下: package org.frzh.thread;    public class FirstThread extends Thread{      private int i;           //重写run方法,run方法的方法体就是线程执

java线程之使用Runnable接口创建线程的方法

实现Runnable接口的类必须使用Thread类的实例才能创建线程.通过Runnable接口创建线程分为两步: 1. 将实现Runnable接口的类实例化. 2. 建立一个Thread对象,并将第一步实例化后的对象作为参数传入Thread类的构造方法. 最后通过Thread类的start方法建立线程. 下面的代码演示了如何使用Runnable接口来创建线程: 复制代码 代码如下: package mythread; public class MyRunnable implements Runn

Java并发编程中使用Executors类创建和管理线程的用法

1. 类 Executors Executors类可以看做一个"工具类".援引JDK1.6 API中的介绍:   此包中所定义的 Executor.ExecutorService.ScheduledExecutorService.ThreadFactory 和 Callable 类的工厂和实用方法.此类支持以下各种方法: (1)创建并返回设置有常用配置字符串的 ExecutorService 的方法. (2)创建并返回设置有常用配置字符串的 ScheduledExecutorServi

了解Java线程池创建过程

前言 最近在改进项目的并发功能,但开发起来磕磕碰碰的.看了好多资料,总算加深了认识.于是打算配合查看源代码,总结并发编程的原理. 准备从用得最多的线程池开始,围绕创建.执行.关闭认识线程池整个生命周期的实现原理.后续再研究原子变量.并发容器.阻塞队列.同步工具.锁等等主题.java.util.concurrent里的并发工具用起来不难,但不能仅仅会用,我们要read the fucking source code,哈哈.顺便说声,我用的JDK是1.8. Executor框架 Executor是一

创建并运行一个java线程方法介绍

要解释线程,就必须明白什么是进程. 什么是进程呢? 进程是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间),比如用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间.当用户再次点击左面的IE浏览器,又启动了一个进程,操作系统将为新的进程分配新的独立的地址空间.目前操作系统都支持多进程. 要点:用户每启动一个进程,操作系统就会为该进程分配一个独立的内存空间. 线程--概念 在明白进程后,就比较容易理解线程的概念. 什么是线程呢? 是进程中的一个实体,是被

Java并发编程示例(七):守护线程的创建和运行

Java有一种特殊线程,守护线程,这种线程优先级特别低,只有在同一程序中的其他线程不执行时才会执行. 由于守护线程拥有这些特性,所以,一般用为为程序中的普通线程(也称为用户线程)提供服务.它们一般会有一个无限循环,或用于等待请求服务,或用于执行任务等.它们不可以做任何重要的工作,因为我们不确定他们什么时才能分配到CPU运行时间,而且当没有其他线程执行时,它们就会自动终止.这类线程的一个典型应用就是Java的垃圾回收. 在本节示例中,我们将创建两个线程,一个是普通线程,向队列中写入事件:另外一个是

Java使用Callable和Future创建线程操作示例

本文实例讲述了Java使用Callable和Future创建线程操作.分享给大家供大家参考,具体如下: 一 点睛 从Java 5开始,Java提供了Callable接口,该接口是Runnable接口的增强版,Callable接口提供了一个call()方法,可以看作是线程的执行体,但call()方法比run()方法更强大. call()方法可以有返回值. call()方法可以声明抛出异常. 创建并启动线程的步骤如下: 1 创建Callable接口的实现类,并实现call()方法,该call()方法

详解JDK中ExecutorService与Callable和Future对线程的支持

详解JDK中ExecutorService与Callable和Future对线程的支持 1.代码背景: 假如有Thread1.Thread2.Thread3.Thread4四条线程分别统计C.D.E.F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现? 2.代码: 统计"盘子"大小的代码,此处实现jdk中的Callable接口, package com.wang.test.concurrent; import java.util.concurrent.Cal

java通过Callable和Future来接收线程池的执行结果

在Java的线程执行中,不管是直接继承Thread的方式,还是实现Runnable接口的方式,都不会获取到线程执行的返回结果.这样如果线程在执行过程中出现了错误,那么主线程也不会感知到.即使打印了日志,也不能立即抛出异常.事后查看日志才能发现出现了bug.而且到那时发生问题的代码点距离真正的问题点可能会相差很远.如果在线程池执行的过程中出现了bug能及时地抛出异常,那么这将会是一个很好的实现.解决上述问题的办法是使用Callable接口,其可以获取到线程的返回结果,通过Future的get方法来

Java多线程Callable和Future接口区别

Runnable是执行工作的独立任务,但是不返回任何值.如果我们希望任务完成之后有返回值,可以实现Callable接口.在JavaSE5中引入的Callable是一个具有类型参数的范型,他的类型参数方法表示为方法call()而不是run()中返回的值,并且必须使用ExecutorService.submint()方法进行调用. 代码如下 import java.util.concurrent.Callable; import java.util.concurrent.ExecutionExcep

Java继承Thread类创建线程类示例

本文实例讲述了Java继承Thread类创建线程类.分享给大家供大家参考,具体如下: 一 点睛 通过继承Thread类创建线程并启动多线程的步骤: 1 定义Thread的子类,并重写该类的run()方法,该run()方法的方法体代表了线程需要完成的任务.因此run()方法称为线程执行体. 2 创建Thread子类的实例,即创建子线程对象. 3 调用线程对象的start()方法来启动该线程. 二 代码 // 通过继承Thread类来创建线程类 public class FirstThread ex

Java后台线程操作示例【守护线程】

本文实例讲述了Java后台线程操作.分享给大家供大家参考,具体如下: 一 点睛 有一种线程,它是后面运行的,它的任务是为其他线程提供服务,这种线程被称为"后台"线程,又称为"守护线程"或"精灵线程".JVM的垃圾回收线程就是典型的后台线程. 后台线程有个特征:如果所有的前台线程都死亡,后台线程会自动死亡, 调用Thread对象的setDaemon(true)方法可将指定线程设置成后台线程,所有的前台线程都死亡时,后台线程随之死亡.当整个虚拟机中只

Java中断一个线程操作示例

本文实例讲述了Java中断一个线程操作.分享给大家供大家参考,具体如下: 一 点睛 中断一个线程,意味着该线程在完成任务之前,停止它正在进行的一切当前的操作. 有三个比较常用的函数: interrupt():一个正在运行的A线程,可以调用B线程对应的interrupt方法来中断线程B.这个方法的核心功能是,将线程B的中断标识位属性设置为true. isInterrupted():通过该方法判断某个线程是否处于中断状态. interrupted():这是一个静态方法,用来获取当前线程的中断状态,并

Java实现动态创建类操作示例

本文实例讲述了Java实现动态创建类操作.分享给大家供大家参考,具体如下: Java可以创建动态类,学习看到,此处作为笔记. 代码如下: import java.io.IOException; import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.tools.Java

Spring实战之调用实例工厂方法创建Bean操作示例

本文实例讲述了Spring实战之调用实例工厂方法创建Bean操作.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" x

Spring实战之使用静态工厂方法创建Bean操作示例

本文实例讲述了Spring实战之使用静态工厂方法创建Bean操作.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" x