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. pyqt5猜数小程序

    程序界面用qt设计师制作,并用pyuic5命令转换成form.py文件 #-*- coding:utf-8 -*- from PyQt5.QtWidgets import QApplication,Q ...

  2. thinkphp 5.0 lnmp环境下 无法访问,报错500(public目录)

    两种方法: 1.修改fastcgi的配置文件 /usr/local/nginx/conf/fastcgi.conf fastcgi_param PHP_ADMIN_VALUE "open_b ...

  3. iOS 11开发教程(一)

    iOS 11开发概述 iOS 11是目前苹果公司用于苹果手机和苹果平板电脑的最新的操作系统.该操作系统的测试版于2017年6月6号(北京时间)被发布.本章将主要讲解iOS 11的新特性.以及使用Xco ...

  4. Visual Studio 2017强制更新方法

    Visual Studio 2017强制更新方法   Visual Studio 2017更新时候,用户都是根据消息提示,进行更新.这样做的好处,就是微软可以分批下发升级包,避免集中更新.不过为了早点 ...

  5. collection 和 collections

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha collection 是集合的意思. 集合 是 集合类的上级接口, 比如 set 和 l ...

  6. css选择器(第n个类选择器)的坑

    css选择器选择第n个子元素,共有两种写法: .parent span:nth-child(n) 选择parent下的第n个子元素(不管前边是不是span,都算在内) .parent span:nth ...

  7. 为什么Android手机总是越用越慢?

    根据第三方的调研数据显示,有77%的Android手机用户承认自己曾遭遇过手机变慢的影响,百度搜索“Android+卡慢”,也有超过460万条结果.在业内,Android手机一直有着“越用越慢”的口碑 ...

  8. centos7安装kafka_2.11-1.0.0 新手入门

    系统环境 1.操作系统:64位CentOS Linux release 7.2.1511 (Core) 2.jdk版本:1.8.0_121 3.zookeeper版本:zookeeper-3.4.9. ...

  9. Linux rescue

    适用场景: 当误操作修改系统启动文件/etc/fstab, /etc/rc.d/rc.sysinit时,就会造成系统启动时读取磁盘或初始化环境失败,导致linux无法正常启动,此时就可以借助Linux ...

  10. Git_操作标签

    如果标签打错了,也可以删除: $ git tag -d v0.1 Deleted tag 'v0.1' (was e078af9) 因为创建的标签都只存储在本地,不会自动推送到远程.所以,打错的标签可 ...