------- android培训、 java培训、期待与您交流! ---------
什么是线程:
进程中的一个独立的控制单元。
线程在控制着进程的执行
线程会开启一个新的执行单元
启动jvm时会有一个进程java.exe
该进程有至少一个线程负责
该线程代码存在于main方法
该线程为主线程
创建线程的两种方式?
一、继承Thread类
1.定义类继承Thread类
2.复写run方法
将自定义的代码存储在run方法中
3.调用线程的start方法
该方法两个作用:启动线程,调用run方法
public class ThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建,并初始化Demo类型对象d
Demo d = new Demo("one_*");
// 启动线程t1
d.start();
}
}
class Demo extends Thread {
Demo(String name){
super(name);
}
// 重载run函数
public void run() {
System.out.println("-----demo run----");
}
}
二、实现Runnable接口
class Ticket implements Runnable{
//实现 Runnable接口
//重写 Runnable接口中的run()方法
public void run() {
System.out.println("-----demo run----");
}
}
public class ThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建,并初始化Ticket对象t
Ticket t = new Ticket();
// 通过Thread创建线程
Thread t1 = new Thread(t);
// 启动线程t1
t1.start();
}
}
线程类的一些常用方法:
sleep(): 强迫一个线程睡眠n毫秒。
isAlive(): 判断一个线程是否存活。
join(): 等待线程终止。
activeCount(): 程序中活跃的线程数。
enumerate(): 枚举程序中的线程。
currentThread(): 得到当前线程。
isDaemon(): 一个线程是否为守护线程。
setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束)
setName(): 为线程设置一个名称。
wait(): 强迫一个线程等待。
notify(): 通知一个线程继续运行。
setPriority(): 设置一个线程的优先级。
线程的五种状态
1,新建状态
创建了一个新的线程
2,冻结状态
放弃执行权。sleep。wait。
3,运行状态
就绪状态的线程获取了CPU的执行权
4,阻塞状态
有执行资格,没有执行权
1、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
2、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
3、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者 I/O处理完毕时,线程重新转入就绪状态。
5,死亡状态
退出了run方法,结束了生命周期
线程安全
同步代码块 synchronized(任何对象){
需要同步的代码块
}
对象如同锁,持有锁的线程才能在同步中执行
必须多个线程使用一个共同的锁
同步函数用this锁
静态同步函数用class对象
单例设计模式
在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象
实现方式
饿汉式:在类装载时构建实例。(一般认为这种方式要更加安全些)
懒汉式:在第一次被使用时构建实例。
1:饿汉式
public class Singleton1 {
//构造方式设为private,外部不能访问
private Singleton1() {
}
// 在自己内部定义自己的一个private实例,只供内部调用
private static final Singleton1 s = new Singleton1();
// 提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton1 getInstance() {
return s;
}
}
2:懒汉式
public class Singleton2 {
private static Singleton2 s = null;
private Singleton2{};
public static Singleton2 getInstance() {
if (s == null){
Synchronized(Singleton2.class){
if(s == null)
s = new Singleton2();
}
}
return s;
}
}
线程的通信:
wait()与sleep()的区别:
wait():释放资源释放锁
sleep():释放资源不释放锁
package Thread;
/**
* 线程间通信:
* 多个线程的run方法不同
* 等待线程存在线程池中
* notifyAll()唤醒所以线程
* wait notify notifyall都用在synchronized中
* 因为要对持有监视器(锁)的线程操作
* 为什么要定义在OBJECT类中
*
* 因为这些方法在操作同步中的线程时,都必须要标识他们所操作线程持有的锁
* 只有同一个锁上被等待的线程,可以被同一个锁上notify唤醒
* 不可以对不同锁中的线程进行唤醒
*
* 也就是说,等待和唤醒必须是同一个锁
*
* 而锁可以是任意对象,
*/
class Res{//两个线程都在操作res这个资源
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name,String sex){
if(flag)
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}
public synchronized void out() {
if(!flag)
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "...." + sex);
flag = false;
this.notify();
}
}
class Input implements Runnable{
private Res r;
Input(Res r) {
this.r = r;
}
public void run() {
int x=0;
while(true){
synchronized (r){ //用资源这个锁
if(x==0){
r.set("mike", "man");
}
else{
r.set("丽丽", "女");
}
x = (x+1) % 2;
}
}
}
}
class Output implements Runnable{
private Res r;
Output(Res r) {
this.r = r;
}
public void run() {
while(true){
r.out();
}
}
}
public class ThreadDemo4 {
public static void main(String[] args) {
Res r = new Res();
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
// Input in = new Input(r);
// Output out = new Output(r);
// Thread t1 = new Thread(in);
// Thread t2 = new Thread(out);
// t1.start();
// t2.start();
}
}
------- android培训、java培训、期待与您交流! ---------