Java--进程和线程

一:进程与线程

1.进程(Process)

每个独立运行着的程序称为一个进程.

2.线程(Thread)

线程是一个进程内部的一条执行路径(path),Java虚拟机允许应用程序并发地运行多个执行路径

进程和线程区别:

      进程有独立的地址空间,一个进程崩溃后,不会对其它进程产生影响,而线程只是一个进程中的一个执行路径,如有一条线程崩溃了,可能会影响同进程中的其他的线程。

      线程有自己的栈和局部变量,多个线程共享同一进程的地址空间

      一个进程至少有一个线程

4.多线程

    多线程就是在一个进程中创建多个线程,每个线程完成一个任务

优点:

1) 多线程技术使程序的响应速度更快

2) 提高资源利用率

3) 程序设计更简单

多线程执行特性:

随机性(异步执行)

谁”抢”到cpu,谁执行,宏观上同时执行,微观上同一时刻只能执行一个线程

多核除外

二:线程的创建和启动

两种创建新线程的方式

第一种方式:

将类声明为Thread 的子类并重写run()方法

class MyThread extends Thread{  
        public void run(){
              线程具体执行的代码
         }  
}

创建此线程类的实例并启动:

MyThread thread1 = new MyThread();
thread1.start();    // 启动线程

线程的基本使用方法:

public void start()

使该线程开始执行 

public static Thread currentThread() 

返回对当前正在执行的线程对象的引用

public final String getName()

返回该线程的名称

public final void setName(String name)

改变线程名称 

public final void setDaemon(boolean on)

将该线程标记为守护线程或用户线程 

public static void sleep(long millis) 

线程休眠指定毫秒时间

public final void join()

当前线程必须等待,直到调用join()方法的线程对象所对应的线程运行完毕,

当前线程才恢复执行

public static void yield()

线程礼让,但操作系统可以忽略这个礼让请求 

package thread;
public class MyThread extends Thread{
	public MyThread(){
	}	
	public MyThread(String name){
		super(name);
	}	
	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println(Thread.currentThread().getName()+"正在执行,i="+i);
		}
	}
}
package thread;
public class ThreadDemo {
	public static void main(String[] args)throws Exception {
		MyThread t1=new MyThread("A线程");   // 实例化线程对象
		t1.start();
		MyThread t2=new MyThread("B线程");   
		t2.start();
		try {
			Thread.sleep(5000);   // 当前线程休眠1秒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("***************"+Thread.currentThread().getName()+"正在运行...*****************");
	}
}

运行结果:

package thread;
public class JoinMethod {
	public static void main(String[] args) {
		MyThread mt = new MyThread("我的线程");
		mt.start(); // 启动线程
		for (int i = 0; i <= 100; i++) {
			if (i == 30) {
				try {
					mt.join(); // 当前线程必须等待,直到调用join()方法的线程对象所对应的线程运行完毕,当前线程才恢复执行
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName() + "执行,i=" + i);
		}
	}
}

运行结果:


package thread;
public class YieldMethod {
	public static void main(String[] args) {
		MyThread mt = new MyThread();
		mt.start();
		for (int i = 0; i <= 100; i++) {
			System.out.println(Thread.currentThread().getName() + "执行,i=" + i);
			Thread.yield(); // 给调度程序的一个提示,当前线程愿意放弃它当前的处理器的使用。调度程序可以自由地忽略这个提示。
		}
	}
}

运行结果:


三:线程的生命周期(状态转换)

1.线程的状态:

要想实现多线程,必须在主线程中创建新的线程对象。任何线程都具有五种状态:创建、就绪、运行、阻塞、终止。

2.线程的停止:

如果线程的run()方法中执行的是一个重复执行的循环,可以提供一个标记来控制循环是否执行。

如果线程因为执行sleep()或是wait()而进入了阻塞状态,此时要想停止它,可以使用interrupt(),程序会抛出InterruptException异常。

如果程序因为输入/输出的等待而阻塞,基本上必须等待输入/输出的动作完成才能离开阻塞状态。无法用interrupt()方法来使得线程离开run()方法,要想离开,只能通过引发一个异常。

package stop;
public class LoopThread extends Thread {
	private boolean flag = true;
	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	@Override
	public void run() {
		while (flag) {
			System.out.println(Thread.currentThread().getName() + "正在运行...");
		}
	}
}
package stop;
public class StopLoop {
	public static void main(String[] args) {
		LoopThread lt=new LoopThread();
		lt.start();
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		lt.setFlag(false);
		System.out.println("end..........");
	}
}

运行结果:


package stop;
public class InterruptThread extends Thread {
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "开始执行...");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			System.out.println("为什么叫醒我???!!!");
		}
		System.out.println(Thread.currentThread().getName() + "执行完毕");
	}
}
package stop;
public class StopInterrupt {
	public static void main(String[] args) {
		InterruptThread it=new InterruptThread();
		it.start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		it.interrupt();   // 打断这个线程,使之抛出InterruptedException异常
	}
}

运行结果:


package copy;
import java.io.*;
/*
 * 使用线程将某个目录下的文件复制到另一个目录下,在复制的过程中要显示出
 完成进度(eg:已复制5%,10%...)。要求由客户端决定源文件与目标文件。
 提示:要用到File类的public long length()方法。
 可在复制的过程中使用Thread.sleep(xxx)来放缓复制速度;
 */
public class CopyThread extends Thread {
	private File srcFile;
	private File destFile;
	public CopyThread() {
	}
	public CopyThread(File srcFile, File destFile) {
		this.srcFile = srcFile;
		this.destFile = destFile;
	}
	@Override
	public void run() {
		InputStream input = null;
		OutputStream out = null;
		try {
			input = new FileInputStream(srcFile);
			out = new FileOutputStream(destFile);
			byte[] b = new byte[1024 * 10];
			int len = 0;
			int count = 0; // 用来记录已经写入的字节数
			long totalSize = srcFile.length(); // 要复制的源文件的总大小,以字节计算
			while ((len = input.read(b)) != -1) {
				out.write(b, 0, len);
				count += len;
				int percentage = (int) (count * 1.0 / totalSize * 100);
				System.out.println("已经下载了" + percentage + "%");
				Thread.sleep(1000);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
package copy;
import java.io.File;
public class Test {
	public static void main(String[] args) {
		System.out.println("main方法开始了...");
		File srcFile=new File("c:"+File.separator+"picture.png");
		File destFile=new File("d:"+File.separator+srcFile.getName());
		new CopyThread(srcFile,destFile).start();   // 启动复制线程
		System.out.println("主方法结束...");
	}
}

运行结果:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值