您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
多线程技术(多线程技术的优点)
线程,方法,窗口多线程技术(多线程技术的优点)
发布时间:2020-12-06加入收藏来源:互联网点击:
很多朋友想了解关于多线程技术的一些资料信息,下面是小编整理的与多线程技术相关的内容分享给大家,一起来看看吧。
程序,进程,线程程序:为完成特定任务,使用某种语言编写的一组指令的集合,是一段静态的代码。进程:程序的一次运行过程,或者是正在运行的一个程序。进程是资源分配的基本单位。线程:线程由进程进一步细化而来,是一个程序内部的一条执行路径。线程是调度和执行的单位,每个线程拥有独立的运行栈和程序计数器,线程开销很小。Thread生命周期Thread类中的常用方法start():启动当前线程;调用当前线程的run()。run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中。currentThread():静态方法,返回执行当前代码的线程。getName():获取当前线程的名字。setName():设置当前线程的名字。yield():释放当前cpu的执行权。join():在线程a中调用线程b的join()方法,此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才结束阻塞状态。sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒时间内,当前线程是阻塞状态。isAlive():判断当前线程是否存活。getPriority():获取线程的优先级。setPriority(int p):设置线程的优先级。线程的优先级有以下三种,MAX_PRIORITY:10;MIN _PRIORITY:1;NORM_PRIORITY:5。创建多线程的方式继承Thread类步骤:
创建一个继承于Thread类的子类;重写Thread类中的run()方法,将次线程执行的操作声明在run()方法中。创建Thread类的子类对象。通过此对象调用start()。举例:三个窗口进行卖票(存在线程安全问题)class MThread extends Thread{ private static int tickets = 100; @Override public void run() { while(true){ if(tickets 0){ System.out.println(getName() + "卖票,票号为:" + tickets--); }else{ break; } } }}public class ThreadTest { public static void main(String[] args) { MThread t1 = new MThread (); MThread t2 = new MThread (); MThread t3 = new MThread (); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); }}说明:局限于类的单继承。
实现Runnable接口步骤:
创建一个实现Runnable接口的类。实现类去实现Runnable中的抽象方法:run()。创建实现类的对象。将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象。通过Thread类的对象调用start()。举例:三个窗口进行卖票(存在线程安全问题)class MThread implements Runnable{ private int tickets = 100; @Override public void run() { while(true){ if(tickets 0){ System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + tickets--); }else{ break; } } }}public class ThreadTest { public static void main(String[] args) { MThread m = new MThread(); Thread t1 = new Thread(m); Thread t2 = new Thread(m); Thread t3 = new Thread(m); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); }}说明:不会局限于类的单继承;适合处理多个线程共享数据的情况。
实现Callable接口步骤:
创建一个实现Callable的实现类。实现call方法,将此线程需要执行的操作声明在call()中。创建Callable接口实现类的对象。将此Callable接口实现类的对象作为参数传递到FutureTask构造器中,创建FutureTask的对象。将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()。举例:遍历100以内的偶数,并且计算他们的和class MThread implements Callable{ @Override public Object call() throws Exception { int sum = 0; for (int i = 2; i 101; i+=2) { System.out.println(i); sum += i; } } return sum; }}public class ThreadTest { public static void main(String[] args) { MThread thread = new MThread (); FutureTask futureTask = new FutureTask(thread); new Thread(futureTask).start(); try { //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。 Object sum = futureTask.get(); System.out.println("总和为:" + sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}说明:call()方法有返回值,并且可以抛出异常;callable支持泛型。
线程池步骤:
提供指定线程数量的线程池。执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象。关闭线程池。举例:两个线程遍历100以内的奇偶数class NumberThread implements Runnable{ @Override public void run() { for(int i = 1;i 101; i+=2){ System.out.println(Thread.currentThread().getName() + ": " + i); } }}class NumberThread1 implements Runnable{ @Override public void run() { for(int i = 2;i 101; i+=2){ System.out.println(Thread.currentThread().getName() + ": " + i); } }}public class ThreadPool { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); ThreadPoolExecutor service1 = (ThreadPoolExecutor) service; service.execute(new NumberThread());//适用于Runnable service.execute(new NumberThread1());//适用于Runnable //service.submit(Callable callable);//使用于Callable service.shutdown(); }}说明:提高了响应速度;降低资源消耗;便于线程管理。
线程同步机制解决线程安全问题
同步代码块synchronized(对象){//需要被同步的代码}举例:三个窗口卖票
class Windows extends Thread{ private static int tickets = 100; @Override public void run() { while(true){ synchronized(Windows.class){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if(tickets 0){ System.out.println(getName() + "卖票,票号为:" + tickets--); }else{ break; } } } }}public class Test { public static void main(String[] args) { Windows t1 = new Windows(); Windows t2 = new Windows(); Windows t3 = new Windows(); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); }}同步方法将synchronized放到方法的声明中。举例:三个窗口卖票。
class Windows implements Runnable { private int tickets = 100; @Override public void run() { while(true){ show(); } } private synchronized void show(){ if(tickets 0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + tickets--); } }}public class Test{ public static void main(String[] args) { Windows t = new Windows(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start();t2.start();t3.start(); }}Lockclass A{ private final ReentrantLock lock = new ReentrantLock(); public void m(){ lock.lock(); try{ //保证线程安全的代码 } finally{ lock.unlock(); } }}举例:三个窗口卖票class Window implements Runnable{ private int ticket = 100; private ReentrantLock lock = new ReentrantLock(); @Override public void run() { while(true){ try{ lock.lock(); if(ticket 0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket--); } }finally { lock.unlock(); } } }}public class LockTest { public static void main(String[] args) { Window w = new Window(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("线程1");t2.setName("线程2");t3.setName("线程3"); t1.start();t2.start();t3.start(); }}synchronized和lock对比:lock是显示锁,手动开启和关闭;synchronized是隐式锁,出了作用域自动释放。lock只有代码块锁;synchronized有代码块锁和方法锁。使用lock锁,JVM将花费较少的时间来调度线程,能更好;并且具有更好的扩展。线程通信三个方法wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。)notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。说明wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。wait(),notify(),notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器。否则,会出现IllegalMonitorStateException异常。wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中。举例:生产者消费者问题class Clerk{ private int productCount = 0; public synchronized void produceProduct(){ if(productCount 20){ productCount ++; System.out.println(Thread.currentThread().getName() + "生产第" + productCount + "个产品"); notify(); }else { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void consumeProduct() { if(productCount 0){ System.out.println(Thread.currentThread().getName() + "消费第" + productCount + "个产品"); productCount --; notify(); }else { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } }}class Productor extends Thread{ private Clerk clerk; public Productor(Clerk clerk) { this.clerk = clerk; } @Override public void run() { System.out.println("生产者" + Thread.currentThread().getName() + "开始生产"); while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } clerk.produceProduct(); } }}class Consumer extends Thread{ private Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } @Override public void run() { System.out.println("消费者" + Thread.currentThread().getName() + "取走产品"); while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } clerk.consumeProduct(); } }}public class ProductTest { public static void main(String[] args) { Clerk clerk = new Clerk(); Productor p1 = new Productor(clerk); p1.setName("生产者1"); Consumer c1 = new Consumer(clerk); c1.setName("消费者1"); p1.start();c1.start(); }}最后上一篇:红光实业(红光实业案例简述)
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |