java 如何创建100个线程_Java多线程---线程的创建和使用

Java多线程---线程的创建和使用

主要内容

程序、进程、线程的概念

Java中多线程的创建和使用

1、继承Thread类与Thread类的主要方法

2、实现Runable接口

3、线程的调度与设置优先级

一、程序、进程、线程的概念

1、程序(program):可以理解为一段静态的代码,静态对象。是为了完成特定任务、用某种语言编写的一组指令的集合。

2、进程(process):它是内存中的一段独立的空间,可以负责当前应用程序的运行。当前这个进程负责调度当前程序中的所有运行细节。

进程是一个动态过程,有它自己的产生、存在和消亡的过程。

3、线程(thread):它是位于进程中,负责当前进程中的某个具备独立运行资格的空间。

区别:进程是负责整个程序的运行,而线程是程序中具体的某个独立功能的运行。一个进程中至少应该有一个线程。

4、多线程:

在一个进程中,同时开启多个线程,让多个线程同时去完成某些任务(功能)。

(比如后台服务系统,就可以用多个线程同时响应多个客户的请求)

多线程的目的:提高程序的运行效率。

多线程运行原理:

cpu在线程中做时间片的切换。其实真正电脑中的程序的运行不是同时在运行的。

CPU负责程序的运行,而CPU在运行程序的过程中某个时刻点上,它其实只能运行一个程序。而不是多个程序。

而CPU它可以在多个程序之间进行高速的切换。而切换频率和速度太快,导致人的肉眼看不到。

每个程序就是进程, 而每个进程中会有多个线程,而CPU是在这些线程之间进行切换。

了解了CPU对一个任务的执行过程,我们就必须知道,多线程可以提高程序的运行效率,但不能无限制的开线程。

二、Java中多线程的创建和使用

1、继承Thread类

(1)实例:

package com.TestThread;

/*

* 创建一个子线程,完成1-100之间自然数的输出,同样,主线程也执行这个操作

* 创建多线程的第一种方式:继承java.lang.Thread类

*/

//1、创建一个继承于Thread的子类

class SubThread extends Thread{

//2、重写Thread类的run()方法,方法内实现此子线程要完成的功能

public void run(){

for(int i=1;i<=100;i++){

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

}

}

}

public class TestThread {

public static void main(String[] args) {

//3、创建一个子类的对象

SubThread st1=new SubThread();

SubThread st2=new SubThread();

//4、调用线程的start()方法:启动此线程,调用相应的run()方法

//一个线程只能够执行一次start()方法

//不能通过Thread实现类对象的run()去启动一个线程

st1.start();

//st1.start()

//st1.run()

st2.start();

for(int i=1;i<=100;i++){

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

}

}

}

(2)Thread的常用方法

实例:

package com.TestThread;

/*

* Thread的常用方法

* 1.start():启动线程并执行相应的run()方法

* 2.run():子线程要执行的代码放入run()方法

* 3.currentThread():静态的,调取当前的线程

* 4.getName():获取此线程的名字

* 5.setName():设置此线程 的名字

* 6.yield():调用此方法的线程释放当前CPU的执行权

* 7.join():在A线程中调用B线程的join()方法,表示当执行到此方法,A线程停止执行,直至B线程执行完成,A线程再接着join()之后的代码执行

* 8.isAlive():判断当前线程是否还存活

* 9.sleep(long L):显式地让当前线程睡眠L毫秒

* 10.线程通信:wait() notify() notifyAll()

* 设置线程的优先级:时间片,抢占式

* getPriority():返回线程优先值

* setPriority(int new Priority):改变线程的优先级

*/

class SubThread1 extends Thread{

public void run(){

for(int i=1;i<=100;i++){

/*try {

Thread.currentThread().sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}*/

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

}

}

}

public class TestThread1 {

public static void main(String[] args) {

SubThread1 st1=new SubThread1();

SubThread1 st2=new SubThread1();

st1.setName("子线程1");

st1.start();

st2.setName("子线程2");

st2.start();

Thread.currentThread().setName("=========主线程");

for(int i=1;i<=100;i++){

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

/*if(i%10==0){

Thread.currentThread().yield();

}*/

if(i == 20){

try {

st1.join();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

System.out.println(st1.isAlive());

}

}

(3)设置线程的优先级:时间片,抢占式

getPriority():返回线程优先值

setPriority(int newPriority):改变线程的优先级

MAX_PRIORITY(10) MIN_PRIORITY(1) NORM_PRIORITY(5)

(4)简单练习

模拟火车站售票窗口,开启三个窗口售票,总票数为100

(此程序存在线程安全问题,打印车票时可能出现重复车票以及错票,这只是一个简单的实现,没考虑线程安全问题)

package com.TestThread;

//模拟火车站售票窗口,开启三个窗口售票,总票数为100

//方式一:继承Thread类

class Window extends Thread{

static int ticket=100;

public void run(){

while(true){

if(ticket>0){

System.out.println(Thread.currentThread().getName()+"售出的票号为:"+ticket--);

}else{

break;

}

}

}

}

public class TestWindow {

public static void main(String[] args) {

Window w1=new Window();

Window w2=new Window();

Window w3=new Window();

w1.setName("窗口1");

w2.setName("窗口2");

w3.setName("窗口3");

w1.start();

w2.start();

w3.start();

}

}

2、实现Runable接口

(1)实例:

package com.TestThread;

//方式二:实现Runnable接口

//1、创建一个实现了Runnable接口的类

class PrintNum1 implements Runnable{

//2、实现接口的抽象方法

public void run() {

//子类执行的代码

for(int i=1;i<=100;i++){

if(i%2==0){

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

}

}

}

}

public class TestRunnable {

public static void main(String[] args) {

//3、创建一个Runnable接口实现类的对象

PrintNum1 p=new PrintNum1();

//4、将此对象作为形参传递给Thread类的构造器中,创建Thread类的对象,此对象即为一个线程

Thread t1=new Thread(p);

//5、调用start()方法,启动线程并执行run()方法

t1.start();//启动线程,执行Thread对象生成时构造器形参的对象的run()方法

//再创建一个线程

Thread t2=new Thread(p);

t2.start();

}

}

(2)简单练习

模拟火车站售票窗口,开启三个窗口售票,总票数为100

(此程序存在线程安全问题,打印车票时可能出现重复车票以及错票,这只是一个简单的实现,没考虑线程安全问题)

package com.TestThread;

//使用实现Runnable接口方式售票

class Window1 implements Runnable{

int ticket=100;

public void run() {

while(true){

if(ticket>0){

System.out.println(Thread.currentThread().getName()+"售出的票号为:"+ticket--);

}else{

break;

}

}

}

}

public class TestWindow2 {

public static void main(String[] args) {

Window1 w=new Window1();

Thread t1=new Thread(w);

Thread t2=new Thread(w);

Thread t3=new Thread(w);

t1.setName("窗口1");

t2.setName("窗口2");

t3.setName("窗口3");

t1.start();

t2.start();

t3.start();

}

}

3、两种方式的对比

(1)联系:Thread类是实现Runnable接口的。

(2)实现Runnable接口的方式优于继承Thread类的方式

理由:a.避免了Java单继承的局限性

b.如果多个线程要操作同一份资源(或数据),更适合使用实现的方式。

你可能感兴趣的:(java,如何创建100个线程)