线程

线程

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

多进程的意义: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{

	@Override
	public 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{

	@Override
	public 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;
	@Override
	public 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();
	@Override
	public 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() {
			
			@Override
			public 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():终止此计时器,丢弃所有当前已安排的任务.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值