一,线程与进程的区别
进程是程序的一次动态执行过程。它经历了代码从加载,执行到执行完毕的一个完整过程。由于CPU具有分时机制,所以每个进程都能循环获得自己的CPU时间片,由于CPU的执行速度非常快,使得所有的程序好像是在“同时”运行一样。
多线程是实现并发机制的一种有效手段,进程和线程一样,都是实现并发的一个基本单位。
一个进程可能包含了多个同时进行的线程。
二,线程的实现
有两种方法:
1,继承Thread类
Thread类在java.lang包中定义,在子类中必须明确的覆写Thread类中的run()方法。
但是,在启动多线程时,不是直接调用run()方法的,而是通过调用Thread类中的start()方法,在调用start()方法时运行的是run()方法的主体。并且,一个类是通过继承Thread类来实现的,那么只能调用一次start()方法。
看如下代码便于理解:
class MyThread extends Thread
{
private String name;
public MyThread(String name)
{
this.name=name;
}
public void run()
{
for(int i=0;i<10;i++)
{
System.out.print(name+"运行,i="+i);
}
}
public class one1 {
public static void main(String[] args) {
MyThread my1=new MyThread("线程A");
MyThread my2=new MyThread("线程B");
my1.start();
my2.start();
//已经写了一个my1.start()所以不能再写一个my1.start()了,否则会报错
}
}
二,实现Runnable接口
在Runnable接口中只有一个抽象方法run(),但前面提到了,要想启动多线程必须用start()方法,在Runnable接口中没有此方法,所以此时还是要依靠Thread类来实现的,因为在Thread类中提供了public Thread(Runnable target)和public Thread(Runnable target,String name)两个构造方法。
class MyThread implements Runnable
{
private String name;
public MyThread(String name)
{
this.name=name;
}
public void run()
{
for(int i=0;i<10;i++)
{
System.out.print(name+"运行,i="+i);
}
}
public class one1 {
public static void main(String[] args) {
MyThread my1=new MyThread("线程A");
MyThread my2=new MyThread("线程B");
Thread mt1=new Thread(my1);
Thread mt2=new Thread(my2);
mt1.start();
mt2.start();
}
}
三,Thread类和Runnable的区别
Thread类是Runnable接口的子类,在Thread类中的run()方法调用的是Runnable接口中的run()方法。
一个类若继承Thread类则不适合于多个线程的资源共享,而实现了Runnable接口可以方便的实现资源共享。
例如
class MyThread implements Runnable
{
private int ticket=5;
public void run()
{
for(int i=0;i<100;i++)
{
if(ticket>0)
{
System.out.print("卖票"+ticket--);
}
}
}
}
public class one1 {
public static void main(String[] args) {
MyThread my=new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
//实现了资源共享
运行结果为
class MyThread extends Thread
{
private int ticket=5;
public void run()
{
for(int i=0;i<100;i++)
{
if(ticket>0)
{
System.out.print("卖票"+ticket--);
}
}
}
}
public class one1 {
public static void main(String[] args) {
MyThread mt1=new MyThread();
MyThread mt2=new MyThread();
MyThread mt3=new MyThread();
mt1.start();
mt2.start();
mt3.start();
}
}
//没有实现资源共享,运行结果为:卖票5卖票4卖票3卖票2卖票1卖票5卖票4卖票3卖票2卖票1卖票5卖票4卖票3卖票2卖票1
四,线程的状态
线程一般具有五种状态
1,创建状态
此时已经有了相应的内存空间和其他资源,但还处于不可运行的状态。
2,就绪状态
调用了start()方法
3,运行状态
调用了run()方法
4,堵塞状态
在可执行的状态下如果调用了sleep(),suspend(),wait()等方法,线程都将进入堵塞状态。
5,死亡状态线程调用stop()方法或run()方法执行结束后,即处于死亡状态。不具备运行能力。
其他
JAVA程序每次运行的时候至少启动两个线程:main线程+垃圾收集线程
使用Runnable接口实现多线程的资源共享,操作同一资源时,可能会出现资源的同步问题
为解决这一问题有两种方法:1,使用synchronized(同步对象){需要同步的代码}
2,使用同步方法 (使用synchronized关键字将一个方法声明为同步方法)
synchronized 方法返回值 方法名称(参数列表){}
多个线程共享同一资源时需要进行同步,以保证资源操作的完整性,但过多的同步就有可能产生死锁