多线程简单实例

主函数:

package com.thread;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class WorkThreadSample {
	public static void main(String args[]) throws InterruptedException {
		// 任务List: 15个任务
		List<Work> workList = new ArrayList<Work>();
		for (int i = 0; i < 4; i++) {
			workList.add(new Work("任务" + i));
		}
		// 执行任务的线程:3个
		for (int i = 0; i < 3; i++) {
			WorkThread thread = new WorkThread(workList, "线程" + i);// 线程名,需要什么参数可以向里面传递。
			thread.start();// 启动线程
		}

		/*
		 * 睡眠6秒后,线程已经执行完毕,这时候会发现刚刚运行的线程已经没有了, 所以,线程在执行完run方法后,JVM会自动回收处理。
		 * 不用我们手动释放。
		 * 将下面的代码注释注释掉,可以看到线程在执行完run方法后,就自动回收了,已经没有Thread-0,Thread-1,Thread-2 了。
		 */
//		new Thread().sleep(6000);
//		/**
//		 * 在Java的文档中为我们提供了Thread类的完整文档
//		 */
//		// 在Thread对象中取得所有的线程所在的栈,然后取得Set对象,便利取得所有的线程
//		Iterator iterator = Thread.getAllStackTraces().keySet().iterator();
//		Thread myThread = null;
//		while (iterator.hasNext()) {
//			Thread t = (Thread) iterator.next();
//			System.err.println("=========iterator.next():" + t.getName());
//			boolean alive = t.isAlive();
//			System.out.println(t+"的状态为:" + alive);
//			// 根据线程名取得自己想要的线程
//			if (t.getName().equals("Thread-1") && alive) {
//				myThread = t;
//				System.err.println("===线程名,优先级,线程组=======:" + myThread.toString());
//				break;
//			}
//		}

	}
}

业务类:

package com.thread;

public class Work {
	// 任务名
	private String name = null;

	public Work(String name) {
		this.name = name;
	}

	// 任务内容
	public void work(String worker) {
		try {
			new Thread().sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	    System.out.println(worker + "线程:" + name + "结束!");
	}
}

线程类:

package com.thread;

import java.util.List;

public class WorkThread extends Thread{
	 // 线程名
    public String name = null;
    // 任务List
    private List<Work> workList = null;
    public WorkThread(List<Work> workList, String name) {
		this.name = name;
		this.workList = workList;
	}

	public void run() {
        System.out.println(name + " 线程开始执行...");
        while (true) {
        	  Work work = null;
        	  {//同步代码块
		            // 同步锁,放在循环里是不让该线程一直占用workList
		        	synchronized (workList) {
		                // 任务List中有任务时进行循环
		                if (workList != null && !workList.isEmpty()) {
		                    // 取得一个任务,并从任务List中删除该任务
		                    work = workList.remove(0);
		                   // System.out.println("------------"+workList.size());
		                } else {
		                    // 所有任务都完成
		                    break;
		                }
		            }
		        	/**
		        	 * 注意这里不能放在synchronized 中,否则就只能一个一个 的执行了,达不到多线程并发的需求,所以讲业务放到外面,用一个同步代码块包裹,这样就运行更快。
		        	 *  执行任务,例:
		        	 */
		            work.work(name);
        	  }
        }
        System.out.println(name+"执行完成");
    }
}

运行结果为:

线程1 线程开始执行...
线程2 线程开始执行...
线程0 线程开始执行...
线程2线程:任务1结束!
线程0线程:任务2结束!
线程1线程:任务0结束!
线程2线程:任务3结束!
线程0线程:任务4结束!
线程1线程:任务5结束!
线程1线程:任务8结束!
线程2线程:任务6结束!
线程0线程:任务7结束!
线程1执行完成
线程0执行完成
线程2线程:任务9结束!
线程2执行完成

总结:

①线程创建是消耗一定资源的,所以不能创建太多线程。

②线程执行完run方法后,会自动回收。

③我们对线程上锁,只锁最重要的东西,唯一的东西,不可重复的。其他不用上锁,用同步代码块就可以了。

④每个线程的执行时间不一样长,有的快,有的慢。

⑤线程运行后要跳出while(true) 循环,否则会一直运行。

2017年1月22日17:11:14

时间: 2024-08-28 02:44:36

多线程简单实例的相关文章

Java 多线程 简单实例 (消费者与生成者)的关系

PS::线程这套东西在PHP里完全是不存在的概念,有待进一步的学习: PS::这个实例是根据书本上的知识进行扩展的,理解程度50%左右吧! 1.定义生产消费环境 package second; public class Queue { int value = 0; boolean isEmpty = true; /** * 生产者 * @param v */ public synchronized void put(int v){ if(!isEmpty){//如果存在数据没有被消费 try{

多线程简单实例(3)线程池

为什么要用线程池? 每次用线程的时候都去new一个,不麻烦么.如果线程用到较少可以.当需要大量用到线程时,频繁的创建线程,而且创建线程和销毁带来的开销也会随之增多. 线程池就像一个执行器.而我们需要执行的业务逻辑,在我们编写的实现了Runnable接口的run方法里面. 需要执行就扔到线程池里,我只要保证我的业务逻辑在run里面已经实现了.执行找线程池这个代工. 线程池ThreadPoolExecutor类,下面是该类的构造方法. public class ThreadPoolExecutor

多线程简单实例(1)真的需要synchronized么?

说道多线程的安全问题,很多人想到就就是加锁.用到synchronized关键字. 那就要先说说synchronized问什么能够保证线程安全了. 首先要了解线程的工作方式:线程工作分为工作内存和主内存.主内存就是堆和静态区.当线程运行时,首先将主内存的数据拿到工作内存 然后在工作内存中运行,再将数据写回主内存.工作内存是私有的,但是主内存却是共享的. 那么线程不安全的主要根源就是不能线程读写主内存的共享数据. 那么判断要不要加锁,在什么位置加锁就有了依据--共享数据 下面看一个例子: packa

多线程简单实例(2)生产者和消费者

这是一个生产者和消费者的例子.消费者从仓库取物品,生产者向仓库增加商品. 当商品说达到最大时,不能继续增加商品,应该通知其他线程去取商品. 同样,当仓库商品为空时,无法取商品,而是通知其他线程增加商品. 这里用到线程的两个常用的方法:notifyAll和wait方法. package code.thread; //Product and Custom public class ProAndCus { public static void main(String[] args) { Store s

Cr多线程编程简单实例

国家using System; using System.Collections;using System.Collections.Generic;using System.Threading; /// <summary>/// 在开发中经常会遇到线程的例子,如果某个后台操作比较费时间,我们就可以启动一个线程去执行那个费时的操作,同时程序继续执行.在某些情况下可能会出现多个线程的同步协同的问题,下面的例子就展示了在两个线程之间如何协同工作.//////这个程序的思路是共同做一件事情(从一个Ar

c# 多线程 创建对象实例

本次的标题是我在写单例模式的博客时遇到的问题,所以今天专门写了的demo让自己记住怎么简单的使用多线程. 一直纠结的是怎么在for循环中多次实例化对象,好复现单例模式在没有加锁的情况下出现多个实例对象的错误. 先给大家看一下我简单实现的多线程实例对象. 方案一: Demo.cs public class Demo { private static Demo _demo = null; /// <summary> /// 构造函数 /// </summary> private Dem

Java的多线程 简单入门

Java的多线程 简单入门 首先可以先搞清楚什么是程序.进程.线程,以及它们之间的关系: 定义: 一 程序只是一组指令的有序集合,它是静态的 二 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位: 三 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程: 进程与线程区别与联系 (

JAVA RMI远程方法调用简单实例[转]

RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外 一台计算机上的对象来获取远程数据.RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径.在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对 象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote

WPF单线程定时器 简单实例

//窗体加载完毕 void MyMessageBox_Loaded(object sender, RoutedEventArgs e) { //启动定时期倒计时,多线程计时 //System.Threading.Timer timer: //启动单线程计时 System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = new Tim