0
点赞
收藏
分享

微信扫一扫

5、进程与线程


进程与线程

1、  进程是程序的一次动态执行过程,它经历了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程

2、  线程Thread是进程下更小的执行单位,同一进程下的多个线程可以同时执行,叫多线程

 

 

线程的使用

1、  线程可以通过继承Thread类或Runnable接口来实现,线程启动后会默认调用类中的run方法,如下

class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name = name;
}
//线程默认调用的方法
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}

 

2、  使用Thread定义线程,并使用

class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name = name;
}
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread("thread one");
MyThread t2 =new MyThread("thread two");
t1.run();
t2.run();
}
}

执行后发现,程序在按顺序执行,显然多线程并没有启动。要启动线程,需要将t1.run()与t2.run()修改为t1.start()和t2.start()才可以,start表示启动线程,而线程启动后会直接去调用类中的run()方法。

 

3、  使用Runnable定义线程,并使用

class MyThread implements Runnable{
private String name;
public MyThread(String name){
this.name = name;
}
publicvoid run(){
for(int i=1; i<=10; i++){
System.out.println(this.name +": "+ i);
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread("thread one");
MyThread t2 =new MyThread("thread two");
Thread td1 =new Thread(t1); //启动仍需通过Thread对象
Thread td2 =new Thread(t2); //启动仍需通过Thread对象
td1.start();
td2.start();
}
}

Runnable接口定义的线程如果要启动仍然需要通过Thread对象,这是主要的区别

 

4、  Thread类与Runable接口的区别

一个类如果继承了Thread类,则多线程不适合进行资源共享;而实现了Runnable接口则可以方便的实现资源共享

可以通过Thread.currentThread().getName()获取当前线程对象和线程名称

 

继承Thread类如下,共5张票,但是每个线程都卖出了5张票,这是不对的

class MyThread extends Thread{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()
+" sold ticket: "+ ticket--);
}
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
//声明了两个线程对象,两个线程都拥有自己单独的资源
MyThread t1 =new MyThread();
MyThread t2 =new MyThread();
//分别启动两个线程,因为两个线程的资源不是共享的
//所以每个线程会发5张票,这就不对了
t1.start();
t2.start();
}
}

实现Runnable接口的类如下,共5张票,两个线程共输出5张票,结果正确

通过Thread.currentThread()可获取当前线程对象

通过Thread.currentThread().getName()可以获取当前线程对象名

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()
+" sold ticket: "+ ticket--);
}
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
//声明一个资源对象
MyThread t1 =new MyThread();
//启动两个线程,两个线程共享t1内的资源,实现资源共享
Thread td1 =new Thread(t1);
Thread td2 =new Thread(t1);
td1.start();
td2.start();
}
}

 

 

JVM、进程与线程

1、  Java编写的程序都运行在jvm中,每一个程序启动时,都会启动一个JVM,这个JVM实际上就是进程

2、  一个java程序至少启动两个线程,一个是main函数线程,一个是程序的垃圾收集线程

 

 

线程状态

1、  创建:Thread t =new Thread();

2、  就绪:t.start();线程启动后就进入操作系统排队,排到了就调用run方法运行

3、  运行:t.run(); 由系统调用运行

4、  堵塞:sleep();suspend();wait()时,线程暂停执行

5、  死亡:stop()或run()结束时

 

 

线程同步与死锁

1、  实现了Runnable接口的类,类中的属性由多个线程共享,这时如果多个线程同时操作一个资源时就会出问题,所以出现了线程同步问题,如下

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
if(ticket>0){
try{
//sleep后线程紧密排队,导致资源争抢
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);
}
}
}
}

publicclass hello{
publicstaticvoid main(String args[]){
MyThread t1 =new MyThread();
Thread td1 =new Thread(t1);
Thread td2 =new Thread(t1);
td1.start();
td2.start();
}
}

 

2、  线程同步,指同一时间内,只允许一个线程对资源进行操作,其它线程排队直到前一个线程完成

 

3、  同步代码块,synchronized(同步对象){需同步代码},如下

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
//同步其中的代码块,防止资源争抢,一般使用this,意思是对当前对象进行同步
//同一时间只允许一个线程访问this(当前)对象,而this对象中包含共享资源ticket
synchronized(this){
if(ticket>0){
try{
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);
}
}
}
}
}

 

4、  同步方法,锁定了该方法同一时间只能有一个线程对其进行调用,如下

class MyThread implements Runnable{
privateint ticket =5;
publicvoid run(){
for(int i=1; i<100; i++){
sale();
}
}
//同步方法,
privatesynchronizedvoid sale(){
if(ticket>0){
try{
Thread.sleep(300);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sold ticket : "+ ticket--);
}
}
}

 

 

同步与死锁

1、  当需要解决资源共享时,要使用同步来解决

2、  当同步过多时,会出现死锁问题

 

举报

相关推荐

进程与线程

【进程与线程】

【多线程】进程与线程

(一)进程与线程

进程与线程(四)

谈谈进程与线程

0 条评论