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. Java拾遗补缺

    JDK9的lib目录下已经不再包含dt.jar和tool.jar.

  2. CentOS配置远程日志服务器

    (1).发送日志的服务器(被收集) [root@xuexi ~]# vim /etc/rsyslog.conf //在#*.* @@remote-host:514行下添加一行 *.* @@192.16 ...

  3. shell run 屏蔽一切log

    &命令: xxx >/dev/null 2>&1 &                           屏蔽一切logxxx >/tmp/xxx.log 2 ...

  4. 【基础知识】Asp.Net基础三

    服务器端控件一般用于访问量不高的网站,要做到物尽其用. 服务器端控件: FIleUpload控件:向服务器上传文件 if (this.FileUpload1.HasFile) { // Path.Ge ...

  5. linux命令大全之cal命令详解(显示日历)

    cal命令可以用来显示公历(阳历)日历. 1.命令格式:cal [参数][月份][年份] 2.命令功能:用于查看日历等时间信息,如只有一个参数,则表示年份(1-9999),如有两个参数,则表示月份和年 ...

  6. java知识点总结

    一.java 1.容器 1)List Java中ArrayList和LinkedList区别 2)Set 理解HashSet及使用 HashMap和HashSet的区别 3Map HashMap的容量 ...

  7. 一个完成的spring xml配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  8. SLF4J versions 1.4.0 and later requires log4j 1.2.12 or later 终极解决

    http://blog.sina.com.cn/s/blog_54eb26870100uynj.html 到SLF4J官方网站:http://www.slf4j.org/codes.html#log4 ...

  9. BZOJ 3751: [NOIP2014]解方程 数学

    3751: [NOIP2014]解方程 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3751 Description 已知多项式方程: ...

  10. poj 1330 Nearest Common Ancestors 单次LCA/DFS

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19919   Accept ...