线程

来源:互联网 发布:js radio 美化样式 编辑:程序博客网 时间:2024/06/03 12:55

线程

进程:进程是系统分配资源调用的一个独立单位.

多进程的意义:1>目前计算机就是一种多进程,在做一件事情的同时还可以做另一件事情.2>多进程是为了提高计算机CPU的使用率.

单线程:程序的执行路劲只有一条.

多线程:程序的执行路劲有多条.特点:具有随机性!

多线程程序实现方式1:

1)自定一个类:MyThread 继承自Thread类

2)在MyThread类中重写Thread类中的run() .

3)在主线程中,创建该类的实例对象,启动线程

获取线程的名称:

public final String getName()返回该线程的名称.

设置线程名称:

public final void setName(String name)改变线程名称,使之与参数 name 相同.

其他方法:

public final void join()throws InterruptedException等待该线程终止.

public final int getPriority()返回线程的优先级.优先级大的抢占到CPU的执行权大,并不代表就一定能抢到,因为线程的执行具有随机性!

public static void yield()暂停当前正在执行的线程对象,并执行其他线程.暂停当前线程执行其他线程,并不保证另一个线程就一定能抢占到CPU的执行权.

public final void setDaemon(boolean on) :on指定true,就是设置守护线程.jvm自动退出,对于主线程的数据如果直接输出完毕,对于两个守护线程来说不会立即消失,Jvm等会就

动退出.

public static void sleep(long millis)throws InterruptedException在指定的毫秒数内让当前正在执行的线程休眠(暂停执行).

线程停止:public final void stop():强迫线程停止执行.方法过时.

public void interrupt()中断线程.表示中断线程一种状态

相关代码:

public class ThreadDemo {public static void main(String[] args) {MyThread myThread = new MyThread();myThread.start();try {Thread.sleep(3000);Thread.interrupted();} catch (InterruptedException e) {e.printStackTrace();}}}
import java.util.Date;public class MyThread extends Thread{@Overridepublic void run() {System.out.println("开始执行:"+new Date());try {Thread.sleep(10000);} catch (InterruptedException e) {System.out.println("线程终止");}System.out.println("结束执行:"+new Date());}}
多线程实现的第二种方式:

开发步骤:

1)自定义一个类MyRunnable,该类实现Runnable接口.

2)实现该接口中的run()方法.

3)在主线程中创建该类的实例对象,

4)创建Thread类对象,将3)创建的这个对象作为参数进行传递.

5)分别启动线程.

相关代码:

public class MyRunnable implements Runnable{@Overridepublic void run() {for(int i=0;i<100;i++){System.out.println(Thread.currentThread().getName()+":"+i);}}}
public class RunnableDemo2 {public static void main(String[] args) {MyRunnable my = new MyRunnable() ;Thread t1 = new Thread(my, "立华奏") ;Thread t2 = new Thread(my, "小薰") ;t1.start() ;t2.start() ;}}
检验多线程安全问题的标准(以后在判断一个多线程序是否有安全问题的标准)

1)当前是否是一个多线程环境.

2)多线程环境中是否有共享数据.

3)是否有多条语句对共享数据进行操作.

同步锁定对象:

1)可以Object类型以及任意的Java类型对象

2)如果一个方法进来之后是一个同步代码块,那么同步代码块可以演变成一个同步方法

3)如果是一个静态的同步方法,锁对象是当前类名class属性:类名.class (反射机制:获取一些类的字节码文件对象Class类对象)

例题:某电影院目前正在上映贺岁大片(红高粱,少林寺传奇藏经阁),共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票.

相关代码:

public class SellTicket implements Runnable {//100张票公用private static int ticket=100;//同步锁对象private Object obj=new Object();//任一类的对象private Demo d=new Demo();private int x;@Overridepublic void run() {while(true){if(x%2==0){synchronized (SellTicket.class) {//静态同步方法if(ticket>0){try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+ "正在出售第" + (ticket--) + "张票");}}}else{sellTikcket();}x++;}}private static synchronized void sellTikcket() {if(ticket>0){try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在出售第"+ (ticket--) + "张票");}}}class Demo{}
public class RunnableDemo {public static void main(String[] args) {SellTicket sellticket= new SellTicket();Thread thread = new Thread(sellticket,"窗口1");Thread thread2 = new Thread(sellticket, "窗口2");Thread thread3 = new Thread(sellticket, "窗口3");thread.start();thread2.start();thread3.start();}}

使用同步机制的这种方式解决线程安全问题,但是不知道具体的锁对象在哪里添加,以及在哪里释放.JDK5提供了一个更具体的锁对象:Lock.

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作.

Lock是一个接口,用ReentrantLock子类来实现.

public void lock():获取锁.

public void unlock():试图释放此锁.

相关代码:

import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class SellTicket2 implements Runnable{private static int ticket=100;private Lock lock=new ReentrantLock();@Overridepublic void run() {while(true){try{lock.lock();if(ticket>0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+ "正在出售第" + (ticket--) + "张票");}}finally{lock.unlock();}}}}

同步机制的弊端:1>效率低(每一个线程在抢占到CPU的执行权,会将门关闭,别的线程进不来),2>容易出现死锁.

死锁线程:两个或者两个以上的线程出现了互相等待的情况,就会出现死锁!

面试题:

wait()线程等待,notify(),唤醒单个线程,notifyAll():唤醒所有线程这三个方法为什么不定义到Thread类中呢,而是定义在Object类中?

线程中会存在安全问题,并且解决线程安全问题使用的同步代码块或者同步方法来解决,同步代码块来解决线程安全问题,就存在同步锁对象,谁能代表同步锁对象(Object以及任

的Java类),把它定义到Object类中.

线程组:表示一个线程的集合:Java允许一个线程中有多个线程.

设置线程组名称:

public ThreadGroup(String name):构造一个新的线程组.

Thread类有个构造方法:将创建的线程组对象当参数带入

public Thread(ThreadGroup group,Runnable target,String name){ }

获取线程组对象:

public final ThreadGroup getThreadGroup():返回该线程的线程组.

多线程程序的实现方式3:(很少用到)

线程池:JDK5新增了一个Executors工厂类来产生线程池.

好处:节约成本,很多线程用完不会立即被垃圾处理器处理掉,而是回收到线程池中被利用.

方法:public static ExecutorsService newFixedThreadPool(int nThreads):参数直接指定线程池中有多少个线程.

其返回值是ExecutorsService对象,该对象表示一个线程池.可以执行Runnable或者Callable对象代表的线程.

ExecutorsService接口的方法:Future<?>submit(Runnable task);<T>Future<T>submit<Callable<T> task>返回值:异步计算的结果!

相关代码:

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ExecutorsDemo {public static void main(String[] args) {ExecutorService pool=Executors.newFixedThreadPool(2);pool.submit(new MyRunnable());pool.submit(new MyRunnable());pool.shutdown();}}

import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class CallableDemo {public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService ThreadPool=Executors.newFixedThreadPool(2);Future<Integer> submit = ThreadPool.submit(new MyCallable());Future<Integer> submit2 = ThreadPool.submit(new MyCallable());Integer i1=submit.get();Integer i2=submit2.get();System.out.println(i1);System.out.println(i2);}}
多线程中匿名内部类的方式.

格式:new 类名(具体类,抽象类) ,接口(){重写方法}

相关代码:

public class ThreadDemo2 {public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<100;i++){System.out.println(Thread.currentThread().getName()+":"+i);}}}).start();}}
定时器:Timer:

常用的几个方法:

public void schedule(TimerTask task,Date time):安排在指定的时间执行指定的任务.

public void schedule(TimerTask task,long delay):在多少毫秒后执行指定任务.

public void schedule(TimerTask task,long delay,long period):在多少毫秒后,执行任务,并且每个多少毫秒重新执行

public void cancel():终止此计时器,丢弃所有当前已安排的任务.





原创粉丝点击