进程与线程

进程

每个独立执行的程序都是一个进程。
1、程序(任务)的执行过程  --->动态性
2、持有资源(共享内存,共享文件)和线程

例如:
进程:执行QQ
线程:在QQ上可以聊天,收发文件,
线程 是系统中最小的执行单元,一个进程中可以有多个线程,线程共享进程的资源
线程的交互:互斥,同步


Java对线程的支持,线程的创建和启动,线程常用方法,如何停止线程:
继承class Thread方法(java.lang) 实现interface Runnable接口(java.lang)
构造方法,run()方法 run()方法
start()方法,启动线程
sleep()方法,线程休眠
join()方法,使其他线程等待当前线程终止
yield()方法,当前运行线程释放处理器资源
 
获取线程引用,static Thread currentThread(),返回当前运行线程的引用  


多线程:指一个应用程序中,有多条并发执行的线索,每条线索都被称为一个线程。他们会交替执行,彼此之间可以进行通信。


继承Thread:
重写Thread类中的run方法,并且调用start方法用于启动线程。
   
   
package com.buaa.test;
 
public class MyThread extends Thread{
 
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.println("MyThrerad中的run方法");
}
}
}
    
    
package com.buaa.test
 
 
public class Test {
 
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
while(true){
System.out.println("main方法中的线程在运行");
}
}
}



实现Runnable接口:
可以实现资源的共享。 适合多个相同程序代码的线程去处理同一个资源的情况。 可以避免java单继承的局限性。
   
   
package com.buaa.test2;
 
public class PrivateThread implements Runnable{
 
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.println("这里是私人的线程啊......");
}
}
}
   
   
package com.buaa.test2;
 
public class Test2 {
 
public static void main(String[] args) {
PrivateThread pThread = new PrivateThread();
Thread thread = new Thread(pThread);
thread.start();
while(true){
System.out.println("main方法中的线程啊.....");
}
}
}



将某个线程设置成为后台线程:
在某个线程启动之前,就要将其设置为后台线程。即setDaemon()方法必须在start()方法之前调用。
进程中只有后台线程运行时,进程就会结束。但是只要有一个前台线程在运行,这个进程就不会结束。
   
   
package com.buaa.test3;
 
public class DaemonThread implements Runnable{
 
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.println(Thread.currentThread().getName()+"------is running.");
}
}
 
}

   
   
package com.buaa.test3;
 
public class Test3 {
 
public static void main(String[] args) {
DaemonThread dThread = new DaemonThread();
Thread thread =new Thread(dThread,"后台线程");
thread.setDaemon(true); //将thread线程设置成为后台线程
thread.start();
}
}



线程的生命周期:
阻塞原因:等待同步锁,调用IO阻塞方法,调用wait()方法(需要noyify方法唤醒),调用jion()方法,调用sleep()方法。





线程的调度:
java虚拟机按照特定的机制为程序中的每个线程分配CPU的使用权。
线程的调度模型:


优先级用1---10之间的整数来表示,数字越大,优先级越高。
可以用Thread中的setPriority(int newPriority)来设置,
也可以用Thread的静态常量来表示:

  
  
package com.buaa.test4;
 
public class MinPriority implements Runnable{
 
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0 ;i < 10 ;i++){
System.out.println(Thread.currentThread().getName()+"正在输出:"+i);
}
}
 
}

   
   
package com.buaa.test4;
 
public class MaxPrority implements Runnable{
 
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0 ;i < 10 ;i++){
System.out.println(Thread.currentThread().getName()+"正在输出:"+i);
}
}
 
}
    
    
package com.buaa.test4;
 
public class Test4 {
 
public static void main(String[] args) {
Thread maxThread = new Thread(new MaxPriority(),"高优先级");
Thread minThread = new Thread(new MinPriority(),"低优先级");
maxThread.setPriority(10);
minThread.setPriority(Thread.MIN_PRIORITY);
maxThread.start();
minThread.start();
}
}


线程休眠:
静态方法:sleep(long  millis),程序会进入休眠等待状态

   
   
package com.buaa.test5;
 
public class SleepThread implements Runnable{
 
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0 ; i < 10;i++){
if(i==3){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("线程正在输出:"+i);
}
}
 
}
    
    
package com.buaa.test5;
 
public class Test5 {
 
public static void main(String[] args) {
Thread thread = new Thread(new SleepThread());
thread.start();
}
}


线程让步:
通过yield()方法来实现。和sleep()方法一样,都可以让当前线程进入线程暂停,但是yield方法不会阻塞线程,只会让线程转换成就绪状态。当某个线程yield之后,只有和这个线程相同优先级或者是更高的优先级才会获得执行机会。

   
   
package com.buaa.test6;
 
public class YieldThread implements Runnable{
 
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0 ;i <5 ;i++){
System.out.println(Thread.currentThread().getName()+"---------"+i);
if(i==3){
System.out.println("线程让步:");
Thread.yield();
}
}
}
 
}
    
    
package com.buaa.test6;
 
public class Test6 {
 
public static void main(String[] args) {
Thread t1 = new Thread(new YieldThread(),"线程A");
Thread t2 = new Thread(new YieldThread(),"线程B");
t1.start();
t2.start();
}
}




线程插队:
join()方法。当某个线程中调用其他线程的join()放法时,调用的线程将被阻塞,直到被join()方法加入的线程执行完成后才会继续运行。
   
   
package com.buaa.test7;
 
public class EnergencyThread implements Runnable{
 
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0 ; i < 6 ;i++){
System.out.println(Thread.currentThread().getName()+"输入:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
 
}
    
    
package com.buaa.test7;
 
public class Test7 {
public static void main(String[] args) {
Thread t = new Thread(new EnergencyThread(),"插队线程");
t.start();
for(int i = 0 ;i<6 ;i++){
System.out.println(Thread.currentThread().getName()+"输入:"+i);
if(i==2){
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
 
}



多线程同步:
多线程去访问同一个资源时,有可能会有安全问题。为此,需要多线程同步,即限制某个资源在同一时刻只能被一个线程访问。
为了实现这种限制,java提供了一种同步机制。当多个线程使用同一个资源时,可以将处理共享资源的代码放在一个代码块中,使用synchronized关键字进行修饰。成为同步代码块。
   
   
synchronizedlock){
操作资源
}
   lock是锁对象,默认情况下是1。当线程执行同步代码块时,先检查lock标志位,若为1,则可以进入,进入后将编制为置为0。此时外面的新线程会发生阻塞。只有里面的线程出来了,将标志位置1时,新线程才能进入。

同步代码块:
   
   
package com.buaa.test8;
 
public class Ticket1 implements Runnable{
 
private int ticket = 10;
Object lock = new Object();
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (lock) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"卖出的票"+ticket--);
}else{
break;
}
}
}
}
 
}
    
    
package com.buaa.test8;
 
public class Test8 {
 
public static void main(String[] args) {
Ticket1 ticket1 = new Ticket1();
new Thread(ticket1,"线程一").start();
new Thread(ticket1,"线程二").start();
new Thread(ticket1,"线程三").start();
new Thread(ticket1,"线程四").start();
}
}


同步方法:
   
   
synchronized 返回值类型 方法名(参数一,参数二){
}
被synchronized修饰的方法某一时刻只能允许一个线程访问,访问该方法的其他线程都会发生阻塞,直到当前线程访问完毕后,其他线程才有机会执行。

   
   
package com.buaa.test9;
 
public class TicketMethod implements Runnable{
 
private int tickets = 10;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
saleTicket();
if(tickets<=0){
break;
}
}
}
private synchronized void saleTicket() {
// TODO Auto-generated method stub
if(tickets>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖票"+tickets--);
}
}
 
}
    
    
package com.buaa.test9;
 
public class Test9 {
 
public static void main(String[] args) {
 
TicketMethod tMethod = new TicketMethod();
new Thread(tMethod,"线程一").start();
new Thread(tMethod,"线程二").start();
new Thread(tMethod,"线程三").start();
new Thread(tMethod,"线程四").start();
}
}

同步方法也有锁,它的锁是当前调用该方法的对象,也就是this指向的对象。



多线程通信:
在几个线程协同完成工作时,需要线程间的通信。
wait()、notify()、notifyAll()方法,解决线程间的通信。


sleep()、yield()和wait()方法的区别
  sleep() yield() wait()
来自于的类 Thread.sleep(1000); Thread.yield(); obj.wait();
机理 使现在运行的线程暂停。在同步代码块中没有释放锁。是静态方法,只能控制当前正在运行的线程休眠,休眠结束后,会返回到就绪状态。 使现在运行的线程暂停。但是不会阻塞该线程,只是将该线程转换成就绪状态,让系统的调度重新调度一次。 wait()方法释放了同步锁进入等待,直到其他线程进入同步锁,并调用notify()方法唤醒该线程为止
适用范围 任何地方 任何地方 同步代码块中,同notify()一起使用
异常情况 需要捕获异常 不需要 不需要
      notify()方法,用于唤醒此同步锁上等待的第一个调用wait()方法的线程。
notifyAll(),唤醒所以等待的线程


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值