(45)Java学习笔记——多线程 / 设置线程 / 线程调度 /线程控制

多线程

并行与并发

并行:逻辑上同时发生,指在某一个时间内同时运行多个程序。

并发:物理上同时发生,指在某一个时间点同时运行多个程序。

java可以通过两种方式实现多线程程序:

一般来说,被线程执行的代码肯定是比较耗时的。

多线程的方式一:

继承Thread类

步骤:

------|A / 自定义类MyThread继承Thread类

------|B / MyThread类里面重写run()方法

**不是类中的所有代码都需要被多线程执行,这个时候,为了区分哪些需要多线程执行,Java提供了Thread类中的run()用来包含那些被多线程执行的代码。

------|C / 创建对象

------|D / 启动线程  start()方法

**Start():首先启动了线程,然后在由JVM调用run()运行方法

范例:

package cn.itcast_01;
/*
 * MyThread
 * 需要重写run()方法
 * 
 */
public class MyThread extends Thread {
	@Override
	public void run() {
		for(int x =0;x<2000;x++){
			System.out.println(x);
		}
	}
}
package cn.itcast_01;
/*
 * 测试类
 * 
 */
public class MyThreadTest_01 {
	public static void main(String[] args) {
		//创建线程对象
/*		MyThread my = new MyThread();
		my.start();
		//IllegalThreadStateException 非法的的线程状态异常
		//my.start();同一个线程不能同时调用两次
*/		
		//创建两个线程对象,才能调用两个线程,不能一个线程调用多次。
		MyThread my1 = new MyThread();
		MyThread my2 = new MyThread();
		my1.start();
		my2.start();

	}
}


获取线程对象的名称

public final String getName()  :获取线程的名称

public final void setName(String name)  :设置线程名称

范例:

package cn.itcast_02;
/*
 * MyThread
 * 
 */
public class MyThread extends Thread {
	@Override
	public void run() {
		for(int x=0; x<1000;x++){
			System.out.println(getName()+":"+x);  //加入获取线程名称的方法
		}
	}
}
package cn.itcast_02;
/*
 * 测试类
 */
public class MyThreadDemo {
	public static void main(String[] args) {
		//创建线程对象
		MyThread my1 = new MyThread();
		MyThread my2 = new MyThread();
		MyThread my3 = new MyThread();
		
		//设置线程名称
		my1.setName("第一线程:");
		my2.setName("第二线程:");
		
		my1.start();
		my2.start();
	}
}

线程调度:

线程的两种调度模型:

A / 分时调度模型  所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片

B / 抢占式调度模型  优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多些。
用到的方法:

public final void setPriority( int newPriority)更改线程优先级

public final int getPriority()  返回线程对象的优先级

线程控制:

线程休眠:

public static void sleep(long millis)

范例:

package cn.itcast_03;

public class ThreadSleep extends Thread {
	@Override
	public void run() {
		for(int x =0; x<500;x++){
			System.out.println(getName()+":"+x);
			
			//睡眠   //会抛出异常
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
		}
	}
}
package cn.itcast_03;
/*
 * 测试方法
 * 
 */
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();
		
	}
}

线程加入: // 等待该线程终止后其它线程才能继续。

public final void join()

package cn.itcast_03;
/*
 * ThreadJoin
 */
public class ThreadJoin extends Thread {
	public void run() {
		for(int x =0; x<500;x++){
			System.out.println(getName()+":"+x);
		}
	}
}
package cn.itcast_03;
/*
 * ThreadJoin测试
 */
public class ThreadJoinDemo {
	public static void main(String[] args) {
		//创建线程对象
		ThreadJoin tj1 = new ThreadJoin();
		ThreadJoin tj2 = new ThreadJoin();
		ThreadJoin tj3 = new ThreadJoin();
		
		tj1.start();	//这个线程加入了jion,必须它走完了后面的线程才能继续
		try {
			tj1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		tj2.start();
		tj3.start();
		
	}
}

线程礼让:  //暂停当前正在执行的对象,并执行其它线程

public static void yield()

package cn.itcast_03;
/*
 * ThreadYield
 * 
 */
public class ThreadYield extends Thread {
	public void run() {
		for(int x =0; x<500;x++){
			System.out.println(getName()+":"+x);
			Thread.yield();		//加入线程礼让
		}
	}
}


package cn.itcast_03;
/*
 * ThreadYield测试
 * 
 */
public class ThreadYieldDemo {
	public static void main(String[] args) {
		//创建线程对象
		ThreadYield ty1 = new ThreadYield();
		ThreadYield ty2 = new ThreadYield();
		ThreadYield ty3 = new ThreadYield();
		
		ty1.start();
		ty2.start();
		ty3.start();
	}
}

后台线程(守护线程):当正在运行的线程都是守护线程是,JAVA虚拟机退出。该方法必须在启动线程前调用。

public final void setDaemon(boolean on)

package cn.itcast_03;
/*
 * ThreadDaemon后台线程
 * 
 */
public class ThreadDaemon extends Thread {
	public void run() {
		for(int x =0; x<500;x++){
			System.out.println(getName()+":"+x);
		}
	}
}

package cn.itcast_03;
/*
 * ThreadDaemon
 * 下列程序中,当td3运行完了,td1和td2就会终止
 */
public class ThreadDaemonDemo {
	public static void main(String[] args) {
		ThreadDaemon td1 = new ThreadDaemon();
		ThreadDaemon td2 = new ThreadDaemon();
		
		td1.setDaemon(true);
		td2.setDaemon(true);
		
		td1.start();
		td2.start();
		
		Thread.currentThread().setName("td3");
		for(int x = 0; x<100;x++){
			System.out.println(x);
		}
		
		
	}
}

中断线程:

public final void stop()   //停止线程,过时了,但是还可以使用。

public void interrupt()  中断线程,

多线程的实现方式二:

Runnable 接口

创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法

思路(步骤):

A / 自定义类MyRunnable 实现Runnable接口

B / 重写run()方法

C / 创建MyRunnable类的对象

D / 创建Thread类的对象,并把C步骤的对象作为参数传递

范例:

package cn.itcast_04;

public class MyRunnable implements Runnable {

	@Override
	public void run() {
		for(int x = 0;x<500;x++){
			//由于实现接口的方式不能直接使用Thread类的方法,可以通过通过获取当前正在执行的线程来调用getName方法
			System.out.println(Thread.currentThread().getName()+":"+x);  
		}

	}

}
package cn.itcast_04;
/*
 * 思路(步骤):
A / 自定义类MyRunnable 实现Runnable接口
B / 重写run()方法
C / 创建MyRunnable类的对象
D / 创建Thread类的对象,并把C步骤的对象作为参数传递
 */
public class RunnableDemo {
	public static void main(String[] args) {
		//创建MyRunnable类的对象
		MyRunnable mr = new MyRunnable();
		
		// 创建Thread类的对象,并把C步骤的对象作为参数传递
		Thread th1 = new Thread(mr);
		Thread th2 = new Thread(mr);
		
		th1.start();
		th2.start();
		
	}
}
两种方式的比较和区别:

方式二解决了单继承的局限性。

















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值