java基础-JAVA之多线程,
java基础-JAVA之多线程,
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
要想了解线程,先了解进程的概念进程:
进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
1、线程的概念:
线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行;一个进程中至少有一个线程。
java中要想实现多线程,有两种手段,
一种是继续Thread类,另外一种是实现Runable接口。
通过继承Thread类来创建线程的方法。类Thread1声明为Thread的子类,它的构造方法定义线程名和起始参数。
程序如下:
public class Thread1 extends Thread {
int k=0;
public Thread1(String name,int k) {
super(name);
this.k = k; }
public void run() //覆盖run方法的线程体
int i = k;
System.out.println();
System.out.print(getName()+": "); while (i<50) {
System.out.print(i+" ");
i+=2; }
System.out.println(getName() +" end!"); }
public static void main (String args[]) {
Thread1 t1 = new Thread1("Thread1",1); //创建线程对象
Thread1 t2 = new Thread1("Thread2",2);
t1.start(); //启动执行线程
t2.start();
System.out.println("activeCount="+t2.activeCount()); } }
2、创建线程的步骤:
1.定义一个类实现Runnable接口,重写接口中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。
2.创建Runnable接口实现类的对象。
3.创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象。(接口可以实现多继承)
4.调用Thread对象的start()方法,启动线程
public class Thread1 extends Thread
{
int k=0;
public Thread1(String name,int k)
{
super(name);
this.k = k;
}
public void run()
}
3、线程的四种状态:
新状态: 一个新产生的线程从新状态开始了它的生命周期。它保持这个状态知道程序start这个线程。
运行状态:当一个新状态的线程被start以后,线程就变成可运行状态,一个线程在此状态下被认为是开始执行其任务
就绪状态:当一个线程等待另外一个线程执行一个任务的时候,该线程就进入就绪状态。当另一个线程给就绪状态的线程发送信号时,该线程才重新切换到运行状态。
休眠状态: 由于一个线程的时间片用完了,该线程从运行状态进入休眠状态。当时间间隔到期或者等待的时间发生了,该状态的线程切换到运行状态。
终止状态: 一个运行状态的线程完成任务或者其他终止条件发生,该线程就切换到终止状态。
4、线程的使用:
4.1、创建一个线程,最简单的方法是创建一个实现Runnable接口的类一个创建线程并开始让它执行的实例:
// 创建一个新的线程
class NewThread implements Runnable {
Thread t;
NewThread() {
// 创建第二个新线程
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // 开始线程
}
// 第二个线程入口
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// 暂停线程
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // 创建一个新线程
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
运行结果如下:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
4.2、通过继承Thread来创建线程:
创建一个线程的第二种方法是创建一个新的类,该类继承Thread类,然后创建一个该类的实例。
继承类必须重写run()方法,该方法是新线程的入口点。它也必须调用start()方法才能执行。
// 通过继承 Thread 创建线程
class NewThread extends Thread {
NewThread() {
// 创建第二个新线程
super("Demo Thread");
System.out.println("Child thread: " + this);
start(); // 开始线程
}
// 第二个线程入口
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// 让线程休眠一会
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ExtendThread {
public static void main(String args[]) {
new NewThread(); // 创建一个新线程
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
编译以上程序运行结果如下:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
5、多线程
有效利用多线程的关键是理解程序是并发执行而不是串行执行的。例如:程序中有两个子系统需要并发执行,这时候就需要利用多线程编程。
通过对多线程的使用,可以编写出非常高效的程序。不过请注意,如果创建太多的线程,程序执行的效率实际上是降低了,而不是提升了。
其中上下文的切换开销也很重要,如果创建了太多的线程,CPU花费在上下文的切换的时间将多于执行程序的时间!
// 文件名 : DisplayMessage.java
// 通过实现 Runnable 接口创建线程
public class DisplayMessage implements Runnable
{
private String message;
public DisplayMessage(String message)
{
this.message = message;
}
public void run()
{
while(true)
{
System.out.println(message);
}
}
}
// 文件名 : GuessANumber.java
// 通过继承 Thread 类创建线程
public class GuessANumber extends Thread
{
private int number;
public GuessANumber(int number)
{
this.number = number;
}
public void run()
{
int counter = 0;
int guess = 0;
do
{
guess = (int) (Math.random() * 100 + 1);
System.out.println(this.getName()
+ " guesses " + guess);
counter++;
}while(guess != number);
System.out.println("** Correct! " + this.getName()
+ " in " + counter + " guesses.**");
}
}
// 文件名 : ThreadClassDemo.java
public class ThreadClassDemo
{
public static void main(String [] args)
{
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
thread1.setDaemon(true);
thread1.setName("hello");
System.out.println("Starting hello thread...");
thread1.start();
Runnable bye = new DisplayMessage("Goodbye");
Thread thread2 = new Thread(bye);
thread2.setPriority(Thread.MIN_PRIORITY);
thread2.setDaemon(true);
System.out.println("Starting goodbye thread...");
thread2.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
thread3.start();
try
{
thread3.join();
}catch(InterruptedException e)
{
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println("main() is ending...");
}
}
运行结果如下,每一次运行的结果都不一样。
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Thread-2 guesses 27
Hello
** Correct! Thread-2 in 102 guesses.**
Hello
Starting thread4...
Hello
Hello
..........remaining result produced.
6、synchronized:
格式:
synchronized(对象)
{
需要同步的代码;
}
格式:
在函数上加上synchronized修饰符即可。
同步可以解决安全问题的根本原因就在那个对象上。
该对象如同锁的功能。
6.1、同步特点:
前提:多个线程
解决问题注意:多个线程使用的是同一个锁对象
6.2、同步好处:
同步解决了多线程的安全问题
6.3、同步的弊端:
当线程很多时,因为每个线程都会去判断同步上的锁,很消耗资源,降低程序的运行效率
相关文章
- 暂无相关文章
用户点评