-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
一、进程和线程的概述
1、进程:
进程:它是"操作系统"中的概念;对于操作系统来说,每个单独运行的"程序"就是一个"进程";
多进程:是指操作系统可以同时维护多个应用程序的同时运行;统一分配资源;
多进程的意义:
1).充分的利用系统资源;
2).可以提高用户的体验度;使用户有非常好的使用体验;
2、线程:
线程:线程是指,由一个"进程"中启动的一个可以独立运行的代码块;它是某个进程的一部分;
线程可以跟"主进程"一同抢夺系统资源;一个主进程可以开出任意多的线程;
多线程:是指一个程序可以开出多个"线程"同时执行;
多线程的意义:
1).充分的利用系统资源;
2).对于一个软件来说,就好像同时在有多个功能在一起运行;
3、多线程程序和单线程程序:
单线程程序:只有一条执行路径;后面的代码必须等待前面的代码执行完毕才能获得执行;
多线程程序:可以有多条执行路径,就好像多个功能在同时运行;
4、并行和并发:
并行:是指两个线程在"某个时间段内",同时在运行;
并发:是指多个线程在"某个时间点上",同时访问同一资源;
二、多线程的实现方式一
1、实现线程的方式一:Java中的线程,使用:Thread类表示;
1).自定义线程类,继承自Thread;
2).重写run();
3).启动线程:
1>.实例化自定义线程类对象;
2>.调用线程对象的start()方法启动线程;
注意:
1).对于同一个Thread(包括子类)对象,不能多次调用start()方法;
2).对于同一个Thread(包括子类)类,可以产生多个对象,每个对象都可以单独start(),成为一个独立的线程;
package cn.hebei.sjz_线程;
/*
* 1、自定义线程类,继承自Thread,2、重写run();
*/
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName() + " i=" + i);
}
}
}
package cn.hebei.sjz_线程;/* * 3.启动线程: * 实例化自定义线程类对象; * 调用线程对象的start()方法启动线程; */public class Demo {public static void main(String[] args) {// 方式1MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();t1.start();// 启动线程t2.start();t3.start();for (int j = 0; j < 100; j++) {System.out.println(Thread.currentThread().getName() + " j=" + j);}}}
Thread类的基本获取和设置方法
public final String getName():获取线程名
public final void setName(String name):设置线程名
public static Thread currentThread():获取任意方法所在的线程名称
package cn.hebei.sjz_线程;
/*
* 获取和设置线程名
*/
public class Demo {
public static void main(String[] args) {
// 方式1
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
t1.start();
t2.start();
t3.start();
t1.setName("xu");
t2.setName("zhao");
t3.setName("le");
for (int j = 0; j < 100; j++) {
System.out.println(Thread.currentThread().getName() + " j=" + j);
}
}
}
1.Java中线程优先级的范围:1--10(从低到高);
2.设置优先级:
getPriority():获取优先级;
setPriority():设置优先级;(范围一定从1--10)
3.注意:我们不要依赖于"线程优先级"的技术,期望某个线程先执行完毕;因为它不保证线程优先级高的
就一定先执行完毕,这个要由"操作系统"来统一调度;"高优先级"的线程只代表:具有更多的机会
被操作系统执行而已,并不代表一定会先执行完毕;另外,如果线程中所做的事情比较简单,线程"优先级"
的效果会不明显;
三、线程控制
线程休眠
public static void sleep(long millis)
线程加入:调用此方法的线程,将会保证先执行完毕,其它线程才可以被执行;
public final void join()
线程礼让:使调用的线程退回到"就绪"状态,等待操作系统再次分配,很有可能被操作系统再次分配到执行权;
public static void yield()
后台线程:如果on为true,则表示为:守护线程
public final void setDaemon(boolean on)
中断线程
public final void stop():不建议使用
public void interrupt():前提条件:线程的内部,一定要处于以下三种阻塞状态时:
1.Object-->wait()
2.Thread-->sleep()
3.Thread-->yield()
当在外部调用线程的interrupt()方法时,将促使上述方法抛出异常;
四、线程的使用方式二
1.自定义类,实现:Runnable接口;
2.重写run()方法;
3.启动线程:
1).实例化自定义类对象;
2).实例化一个Thread对象,并将自定义对象传递给Thread的构造方法;
3).调用Thread对象的start()方法启动线程;
package cn.hebei.sjz_线程;
/*
* 线程的实现方式二
*/
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " i=" + i);
}
}
}
package cn.hebei.sjz_线程;/* * 实现多线程的方式2 */public class Demo {public static void main(String[] args) {//方式2MyRunnable myRun = new MyRunnable();Thread t = new Thread(myRun);t.start();for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + " i= " + i);}}}
1. 同步代码块
synchronized(被锁的对象){
//同步的代码
}
被锁的对象:表示如果当前线程访问"被锁对象"的synchronized的代码块时,其它线程不能访问此代码块,
另外,也不能访问"被锁对象"中的其它synchronized的代码块;
2.同步的好处:解决了多线程并发访问的问题,使多线程并发访问的共享数据能够保持一致性;
3.同步的弊端:使当前的对象的工作效率降低;因为要处理线程同步的问题;
六、线程组
Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
默认情况下,所有的线程都属于主线程组。
1.线程组就是将一些线程统一分组管理;
2.分组后,可以对组内的所有线程做统一的操作:比如:停止线程;
3.线程组:使用:ThreadGroup
4.在Thread类中:
ThreadGroup getThreadGroup():获取线程所在的线程组;
5.一个线程,在默认情况下,都属于"main"线程组;
6.我们可以自行设定线程组:
1).实例化一个ThreadGroup对象;
2).使用Thread的构造方法,指定线程组和相应的线程
Thread(ThreadGroup group, Runnable target) 分配新的 Thread 对象。
7.统一停止线程组内的所有线程:
ThreadGroup-->interrupt():
package cn.hebei.sjz_线程组;
public class Demo {
public static void main(String[] args) {
// ********默认线程组****************
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
System.out.println("t1的线程组:" + t1.getThreadGroup().getName());
System.out.println("t2的线程组:" + t2.getThreadGroup().getName());
// *********自定义线程组***************
ThreadGroup tg = new ThreadGroup("Java基础组");
Thread th1 = new Thread(tg, t1);
Thread th2 = new Thread(tg, t2);
th1.start();
th2.start();
System.out.println("th1所在的线程组:" + th1.getThreadGroup().getName());
System.out.println("th2所在的线程组:" + th2.getThreadGroup().getName());
System.out.println("主程序休息2秒钟......");
try {
Thread.sleep(1000 * 2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("主程序停掉线程组内的所有线程:");
tg.interrupt();
}
}
JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法
public static ExecutorService newCachedThreadPool():创建一个可根据需要创建新线程的线程池
public static ExecutorService newFixedThreadPool(int nThreads):创建一个可重用固定线程数的线程池
public static ExecutorService newSingleThreadExecutor():创建一个使用单个 worker 线程的 Executor,以*队列方式来运行该线程。(
返回值:ExecutorService--线程池
执行线程,并缓存线程对象:
Future<?> submit(Runnable task)
<T> Future<T> submit(Callable<T> task)
package cn.hebei.sjz_线程池;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo {
public static void main(String[] args) {
MyThread t1 = new MyThread();
// 获取一个线程池
ExecutorService service = Executors.newFixedThreadPool(2);
service.submit(t1);
System.out.println("主线程休息2秒钟......");
try {
Thread.sleep(1000 * 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程醒来,再次调用线程......");
service.submit(t1);
}
}
1.实现:Callable接口;
2.重写call()方法
3.启动线程:
1).获取线程池;
2).调用线程池的submit()方法启动并缓存线程;
package cn.hebei.sjz_线程;
import java.util.concurrent.Callable;
public class MyCallable implements Callable {
@Override
public Object call() throws Exception {
for(int i = 0;i < 100 ; i++){
System.out.println("i = " + i);
}
return null;
}
}
package cn.hebei.sjz_线程;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/* * 实现线程的方式3 */public class Demo3 {public static void main(String[] args) {//1.获取线程池ExecutorService service = Executors.newFixedThreadPool(2);//2.调用线程池的submit()方法执行线程MyCallable myCall = new MyCallable();service.submit(myCall);for(int k = 0 ; k < 100 ; k++){System.out.println("k = " + k);}service.shutdown();}}
九、定时器
Java中的定时器:
1.可以在指定的时间,开始做某件事情;
2.可以从指定的时间开始,并且间隔多长时间,会重复的做某件事情;
实现定时器:
1.java.util.TimerTask(抽象类):定义执行的任务
1).自定义类,继承自TimerTask;
2).重写run()方法;(将要执行的任务定义在这里)
2.java.util.Timer(类):计时,并启动任务;
构造方法:
Timer();
成员方法:
public void schedule(TimerTask task, long delay):在指定的delay延迟之后,启动任务task;
public void schedule(TimerTask task,long delay,long period):在指定的延迟之后,启动任务,并间隔指定时间重复的执行任务;
package cn.hebei.sjz_定时器;
import java.util.Timer;
import java.util.TimerTask;
class MyTimerTask extends TimerTask {
private Timer timer;
public MyTimerTask(Timer t) {
this.timer = t;
}
@Override
public void run() {
System.out.println("duang......");
// this.timer.cancel();//如果重复执行,这里就不能取消了;
}
}
public class Demo1 {
public static void main(String[] args) {
Timer timer = new Timer();
System.out.println("3秒后,开始执行,之后每隔1秒重复执行一次......");
// timer.schedule(new MyTimerTask(timer), 1000 * 3);
timer.schedule(new MyTimerTask(timer), 1000 * 3, 1000);
}
}