您的位置:首页 > 编程语言 > Java开发

1.Java基础之多线程

2018-03-20 14:37 204 查看

#1、多线程

 程序:就是用某种编程语言编写的能够执行特定功能的代码,是静态  
 进程:就是执行中的程序,是动态,进程拥有计算机分配的独立的资源(cpu,内存,网络)  
 线程:是程序执行的路径,如果一个进程里只有一个执行路径,叫单线程  
     如果一个进程里有多个执行路径,叫多线程  
 jvm是多线程还是单线程?
 答案是:多线程
 因为虚拟机启动时,需要同时启动垃圾回收线程,否则会产生内存溢出错误

#2、线程的创建和启动

##2.1 继承Thread

 线程的创建与启动方式1:
 创建线程:
  class 类名 extends Thread
 实现线程方法体
  @Override
  void run()  
 是因为不是所有的方法,都用来执行多线程程序,run方法提供一个实现入口,run方法是有虚拟机调用
 线程启动
  start();

##2.2 实现Runnable

线程的创建与启动方式2:
创建线程:
class MyRunnable implements Runnable
实现线程方法体
@Override
void run()  
 线程启动
  Thread thread = new Thread(new MyRunnable());
  thread.start();
使用继承Thread和实现Runnable区别:
继承Thread: 线程代码存放Thread子类run方法中。
实现Runnable:线程代码存在接口的子类的run方法。
使用实现Runnable的好处:
1、打破单继承的局限性
2、多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

#3、线程的常用方法

##3.1设置线程的优先级别

线程的优先级别:
MAX_PRIORITY(10);    
MIN _PRIORITY (1);  
NORM_PRIORITY (5);
线程级别范围:1-10,超出这个范围,运行时会拋异常
默认级别:5,就是不设置的时候,默认是这个级别
设置优先级别的方法:
getPriority() :返回线程优先值 
setPriority(int newPriority) :改变线程的优先级

##3.2线程休眠

线程休眠:
static void sleep(long millis) 
         在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 
特点:
指定时间段内放弃对CPU控制,使其他线程有机会被执行
需要处理中断异常InterruptedException

##3.3线程加入

线程加入:
public final void join() throws InterruptedException等待该线程终止。
例如:
Thread thread01 = new ThreadJoin();
Thread thread02 = new ThreadJoin();
System.out.println("调用thread02线程的join方法开始,主线程会阻塞,开始只i系那个thread02的线程方法");
try {
thread02.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("直到thread02执行完毕以后才会执行该代码,因为主线程调用thread02线程的join方法,被阻塞");

##3.4线程让步

线程让步:
static void yield()  暂停当前正在执行的线程对象,并执行其他线程。   
若优先级不一样,高的先执行  
若优先级一样,会继续抢cpu执行权

##3.5线程停止

线程停止:
@Deprecated 过时方法,不建议使用
public final void stop()
建议使用:
public void interrupt() 中断线程。 

#4、线程的分类

线程分为:
用户线程
守护线程
特点:
1、守护线程是用来服务用户线程的,
2、通过在start()方法前调用thread.setDaemon(true)
 注意:一个进程里面,不能都是守护线程

#5、线程同步

为什么要使用同步?当多个线程同时对共享变量操作,
可能会出现不确定的情况,那么为保证数据计算的准确行,
我们需要在操作的数据所在的对象上增加同步功能,保证数据计算的安全性。

##5.1 synchronized

java中是通过关键字synchronized来实现的
synchronized关键字使用方式:
1、同步方法
//普通方法
public synchronized void add(){
}
或者
//静态方法
public synchronized static void add(){
}
同步普通方法和静态方法的区别:
普通方法同步的是当前对象this
静态方法同步的是类对象类名.class
2、同步代码块
synchronized(obj){
//代码块
}
这时候同步对象可以是任意对象

##5.2 Lock

java1.7之后提供了两个类,可以更加方便的编写线程安全的代码
Lock lock = new ReentrantLock();
提供了锁和解锁的方法:
lock()
unlock()
示例:
public void add(){
try {
//程序进来的时候就锁上
lock.lock();
for (int i = 0; i < 3; i++) {
balance+=1000;
System.out.println(Thread.currentThread().getName()+":"+balance);
}
} catch (Exc
4000
eption e) {

} finally{
//在这里释放锁
lock.unlock();
}
}

##5.3 锁

释放锁:
当前线程的同步方法、同步代码块执行结束
当前线程在同步代码块、同步方法中遇到break、return终止了该代码块、该方法的继续执行。
当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束
当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁
线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行
互斥锁
在Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。
每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。
同步的局限性:导致程序的执行效率要降低
同步方法(非静态的)的锁为this。
同步方法(静态的)的锁为当前类本身。

#6、线程间通信

 线程间通信:是通过继承自Object类的三个方法实现的:  
 wait() 与 notify() 和 notifyAll()
 注意:  
 使用这些方法必须在synchronized方法或synchronized代码块中  
 具体使用方法与特点:
1、wait() 
在当前线程中调用方法:  对象名.wait()
释放cpu,同步资源,进入阻塞
2、notify()
在当前线程中调用方法:  对象名.notify()
能唤醒优先级较高的线程
获得cpu执行权,进入就绪状态
3、notifyAll()
在当前线程中调用方法:  对象名.notifyAll()
唤醒所有资源
所有资源进入就绪状态,去竞争cpu执行权
注意:对象名就是多个线程共享的锁对象,如果不写对象名,那么默认就是当前类的实例
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: