码迷,mamicode.com
首页 > 编程语言 > 详细

进程与线程

时间:2016-05-26 11:35:30      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:

进程

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

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


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


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


继承Thread:
但是没有实现资源共享,四个窗口没有共享同一个售票系统。
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(),
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(),唤醒所以等待的线程


进程与线程

标签:

原文地址:http://blog.csdn.net/shelter_lemon/article/details/51504571

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!