1.利用Thread的子类创建线程

例1.用Thread子类创建多线程程序。

先定义一个Thread的子类,该类的run方法只用来输出一些信息。

package thread;

public class myThread extends Thread{
private static int count=0; public void run() {
int i;
for(i=0;i<100;i++){
count=count+1;
System.out.println("My name is "+getName()+" count="+count);
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public myThread(String name){
super(name);
} }

下面用程序来创建线程对象并运行该线程对象。

package thread;

public class mulThread {

    public static void main(String[] args) {
myThread trFirst,trSecond;
trFirst = new myThread("First Thread");
trSecond = new myThread("Second Thread");
trFirst.start();
trSecond.start();
System.out.println("主线程结束!");
} }

2.实现Runnable接口创建线程

例2. 继承Runnable接口实现多线程。

package thread;

public class ThreadImRunable implements Runnable{
private static int count=0;
private Thread t;
public void run() {
int i;
for(i=0;i<100;i++){
count++;
System.out.println("My name is "+t.getName()+" count="+count);
try {
t.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}
}
} public ThreadImRunable(String name){
t = new Thread(this,name);
} public void start(){
t.start();
}
}

主程序跟前面相同。

package thread;

public class mulThread {

    public static void main(String[] args) {
myThread trFirst,trSecond;
trFirst = new myThread("First Thread");
trSecond = new myThread("Second Thread");
trFirst.start();
trSecond.start();
System.out.println("主线程结束!");
} }

3.使用isAlive()和join()等待子线程结束

例3. join()方法使用示例。

package thread;

public class demoJoin {
public static void main(String[] args){
myThread trFirst,trSecond;
trFirst = new myThread("First Thread");
trSecond = new myThread("Second Thread");
try {
trFirst.start();
trSecond.start();
trFirst.join();
trSecond.join();
} catch (InterruptedException e) {
System.out.println("主线程被中断!");
}
System.out.println("主线程结束!");
}
}

4.设置线程优先级

例4. 设置线程优先级示例。

package thread;

public class clicker extends Thread{
private int click=0;
private volatile boolean running=true;//volatile告诉编译器,不要自作主张为它编译优化
public int getClick(){
return click;
} public void run() {
while(running){
click = click + 1;
}
} public void normalStop(){
running = false;
} }

程序中的循环变量running被声明成volatile,这个关键字告诉编译器,不要自作主张为它进行编译优化。

注意:不要将循环体中“click=click+1”改成“++click”的形式。对于前者,编译器会生成多条命令,执行过程中系统有机会将它中断。而后者只有一条指令,系统不能将其中断,这样其他进程就难以有机会使用CPU。

package thread;

public class demoPri {

    public static void main(String[] args) {
clicker c1High,c2Low;
c1High=new clicker();
c2Low=new clicker();
c1High.setPriority(Thread.NORM_PRIORITY+2);
c2Low.setPriority(Thread.NORM_PRIORITY-2);
c2Low.start();
c1High.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} c1High.normalStop();
c2Low.normalStop(); try {
c1High.join();
c2Low.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("c1High执行循环的次数为:"+c1High.getClick());
System.out.println("c2Low 执行循环的次数为:"+c2Low.getClick());
} }

程序的输出结果为:

c1High执行循环的次数为:427835536
c2Low 执行循环的次数为:396647205

结果表明,优先级高的线程获得了更多的CPU运行时间。

5.线程的互斥

例5. 线程互斥示例。

package thread;

public class mutixThread extends Thread{
private static int count = 0;
private synchronized static void change(Thread t){
count = count + 1;
System.out.println("My name is "+t.getName()+" count="+count);
} public void run() {
int i;
for(i=0;i<100;i++){
change(this);
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} public mutixThread(String name){
super(name);
}
}

下面写一个程序测试它的运行情况。

package thread;

public class demoMutix {
public static void main(String[] args){
mutixThread t1,t2,t3;
t1 = new mutixThread("First Thread");
t2 = new mutixThread("Second Thread");
t3 = new mutixThread("Third Thread");
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} System.out.println("主线程结束");
}
}

程序运行结果如下:

.....
My name is Third Thread count=297
My name is First Thread count=298
My name is Third Thread count=299
My name is Second Thread count=300
主线程结束

6.线程的同步

例6. 线程同步示例。

package thread;

public class commSource {
static boolean flag = true;
static int data;
static int count;
}
package thread;

public class setDataThread extends Thread {
private readDataThread otherThread=null; //存储另外一个线程对象
public void run(){
for(int i=0;i<100;i++){
if(!commSource.flag)
try {
synchronized(this){ //锁定当前对象
wait(); //阻塞自己
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
commSource.flag = false;
commSource.data = (int)(Math.random()*1000);
commSource.count++;
System.out.println("设置数据:"+commSource.data+" count="+commSource.count);
synchronized(otherThread){ //锁定另外一个线程对象
otherThread.notify(); //唤醒另外一个线程对象
}
}
}
public void setOtherThread(readDataThread rt){
otherThread=rt;
}
}
package thread;

public class readDataThread extends Thread{
private setDataThread otherThread = null;
public void run(){
for(int i=0;i<100;i++){
if(commSource.flag)
try {
synchronized(this){
wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
commSource.flag = true;
System.out.println("获得数据:"+commSource.data);
synchronized(otherThread){
otherThread.notify();
}
}
}
public void setOtherThread(setDataThread st){
otherThread = st;
}
}
package thread;

public class demoSynchorny {

    public static void main(String[] args) {
setDataThread str;
readDataThread rtr;
str=new setDataThread();
rtr=new readDataThread();
str.setOtherThread(rtr);
rtr.setOtherThread(str);
str.start();
rtr.start(); } }

输出结果如下:

设置数据:295 count=1
获得数据:295
......
设置数据:974 count=99
获得数据:974
设置数据:526 count=100
获得数据:526

两个线程是严格交替运行的。

7.暂停恢复和停止线程

例7. 自己编写线程的暂停、恢复和停止方法。

package thread;

public class enhanceThread extends Thread {
private static final int STOP = 1;
private static final int RUNNING = 2;
private static final int SUSPEND = 3;
private int state = STOP;
public synchronized void run(){
int cnt = 0;
while(state!=STOP){
if(state==SUSPEND){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
++cnt;
System.out.println("线程正在运行:"+cnt);
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} public void normalStop(){
state = STOP;
} public void normalSuspend(){
state = SUSPEND;
} //恢复线程运行
public synchronized void normalResume(){
state = RUNNING;
notify();
} public enhanceThread(){
state = RUNNING;
}
}
package thread;

public class demoEhanceThread {

    public static void main(String[] args) {
enhanceThread tr;
tr = new enhanceThread();
System.out.println("启动线程!");
tr.start();
try {
Thread.sleep(1000);
System.out.println("将线程挂起!");
tr.normalSuspend();
Thread.sleep(1000);
System.out.println("恢复线程运行!");
tr.normalResume();
Thread.sleep(1000);
System.out.println("终止线程运行!");
tr.normalStop();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

输出结果如下:

启动线程!
线程正在运行:1
线程正在运行:2
线程正在运行:3
线程正在运行:4
线程正在运行:5
线程正在运行:6
线程正在运行:7
线程正在运行:8
线程正在运行:9
线程正在运行:10
将线程挂起!
恢复线程运行!
线程正在运行:11
线程正在运行:12
线程正在运行:13
线程正在运行:14
线程正在运行:15
线程正在运行:16
线程正在运行:17
线程正在运行:18
线程正在运行:19
线程正在运行:20
终止线程运行!

8.生产者-消费者问题实例

例8. 生产者-消费者实例。

package thread;

public class common {
private int production[]; //存放产品的缓冲区
private int count; //产品的实际数目
private int BUFFERSIZE = 6; //缓冲区大小
public common(){
production = new int[BUFFERSIZE];
count = 0;
}
//从缓冲区中取数据
public synchronized int get(){
int result;
while(count<=0)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
result = production[--count];
notifyAll();
return result;
}
//向缓冲区中写数据
public synchronized void put(int newproduct){
while(count>=BUFFERSIZE)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
production[count++]=newproduct;
notifyAll();
}
}
package thread;
//消费者线程
public class consumer extends Thread {
private common comm;
public consumer(common mycomm){
comm = mycomm;
} public synchronized void run(){ //线程体
int i,production;
for(i=1;i<=20;i++){ //消费线程计数
production = comm.get();
System.out.println("得到的数据为:"+production);
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package thread;
//生产者线程
public class producer extends Thread {
private common comm;
public producer(common mycomm){
comm = mycomm;
} public synchronized void run(){
int i;
for(i=1;i<=10;i++){
comm.put(i);
System.out.println("生产的数据为:"+i);
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package thread;

public class producer_consumer {
public static void main(String[] args){
common comm = new common();
producer p1 = new producer(comm);
producer p2 = new producer(comm);
consumer c1 = new consumer(comm);
p1.start();
p2.start();
c1.start();
}
}

程序某次运行结果如下:

生产的数据为:1
得到的数据为:1
生产的数据为:1
得到的数据为:2
生产的数据为:2
生产的数据为:2
生产的数据为:3
得到的数据为:3
生产的数据为:3
生产的数据为:4
得到的数据为:4
生产的数据为:4
生产的数据为:5
得到的数据为:5
生产的数据为:5
得到的数据为:5
生产的数据为:6
生产的数据为:6
得到的数据为:6
生产的数据为:7
生产的数据为:8
得到的数据为:7
得到的数据为:8
生产的数据为:9
生产的数据为:10
得到的数据为:9
得到的数据为:10
生产的数据为:7
得到的数据为:7
生产的数据为:8
得到的数据为:8
生产的数据为:9
得到的数据为:9
生产的数据为:10
得到的数据为:10
得到的数据为:6
得到的数据为:4
得到的数据为:3
得到的数据为:2
得到的数据为:1

结果表明,该程序已经很好地解决了生产者线程和消费者线程间的同步问题。

Java的多线程机制的更多相关文章

  1. Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  2. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  3. Java的多线程机制系列:(三)synchronized的同步原理

    synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在字节码上编译为 ...

  4. 沉淀再出发:再谈java的多线程机制

    沉淀再出发:再谈java的多线程机制 一.前言 自从我们学习了操作系统之后,对于其中的线程和进程就有了非常深刻的理解,但是,我们可能在C,C++语言之中尝试过这些机制,并且做过相应的实验,但是对于ja ...

  5. Java的多线程机制系列:(一)总述及基础概念

    前言 这一系列多线程的文章,一方面是个人对Java现有的多线程机制的学习和记录,另一方面是希望能给不熟悉Java多线程机制.或有一定基础但理解还不够深的读者一个比较全面的介绍,旨在使读者对Java的多 ...

  6. Java的多线程机制系列:(二)缓存一致性和CAS

    一.总线锁定和缓存一致性 这是两个操作系统层面的概念.随着多核时代的到来,并发操作已经成了很正常的现象,操作系统必须要有一些机制和原语,以保证某些基本操作的原子性.首先处理器需要保证读一个字节或写一个 ...

  7. Java中多线程原理详解

    Java是少数的集中支持多线程的语言之一,大多数的语言智能运行单独的一个程序块,无法同时运行不同的多个程序块,Java的多线程机制弥补了这个缺憾,它可以让不同的程序块一起运行,这样可以让程序运行更加顺 ...

  8. Java—事件和多线程机制

    一  事件 1.1 事件源 图形用户界面上每个可能产生事件的组件称为事件源. 1.2 事件监听者 Java系统中注册的用于接收特殊事件的类.不同的事件对应着不同的监听者,要想事件被监听者监听并处理,则 ...

  9. 【转载】Java垃圾回收机制

    原文地址:http://www.importnew.com/19085.html Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联 ...

随机推荐

  1. loadrunner 脚本中文乱码

    loadrunner 脚本中文乱码 1.新建脚本--->选择协议(Http)-->选项-->高级-->选择“支持字符集”并点选“UTF-8”: 2.在回放脚本之前:Vuser- ...

  2. 警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:fhcq-oa' did not find a matching property.

    当你在使用Eclipse运行web项目时,你可能会看到控制台出现: 警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Settin ...

  3. hdoj1102 Constructing Roads(Prime || Kruskal)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意 有n个村庄(编号1~n),给出n个村庄之间的距离,开始时n个村庄之间已经有了q条路,现在需 ...

  4. Servlet的基本架构

    Servlet的基本架构: package test; import java.io.IOException; import javax.servlet.ServletException; impor ...

  5. codevs 1079 回家

    1079 回家 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃 ...

  6. python编程之socket编程基础

    python socket编程,首先需要import   socket模块 首先创建一个socket对象 expl = socket.socket(socket.AF_INET,socket.SOCK ...

  7. Python168的学习笔记5

    关于对csv文件的操作. python标准库中有csv的库,使用非常方便. import csv with open('pingan.csv','rb') as rf: reader = csv.re ...

  8. Splay-Tree理解

    简介 splay tree其实就是不停的旋转,没进行一个操作都要进行旋转:例如,当访问某一个结点的时候,会通过旋转其结点使得该结点变为树根,这样保证其的平均复杂度为O(nlogn); 其的操作包括: ...

  9. 2016 UESTC Training for Data Structures 题解

    题解在下已经写过一次了,所以就不再写了,下面只有代码 题解下载(1):http://pan.baidu.com/s/1hsAUjMs 题解下载(2):http://pan.baidu.com/s/1m ...

  10. UVALive 5059 C - Playing With Stones 博弈论Sg函数

    C - Playing With Stones Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu S ...