通过实现Runnable接口:
/**
* @author Rollen-Holt 实现Runnable接口
* */
class hello implements Runnable {
private String name;
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "运行 " + i);
}
}
public static void main(String[] args) {
hello h1=new hello("线程A");
Thread demo= new Thread(h1);
hello h2=new hello("线程B");
Thread demo1=new Thread(h2);
demo.start();
demo1.start();
}
}
【可能的运行结果】:
线程A运行 0
线程B运行 0
线程B运行 1
线程B运行 2
线程B运行 3
线程B运行 4
线程A运行 1
线程A运行 2
线程A运行 3
线程A运行 4
Thread和Runnable的区别:
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
/**
* @author Rollen-Holt 继承Thread类,不能资源共享
* */
class hello extends Thread {
private int count = 5;
public void run() {
for (int i = 0; i < 7; i++) {
if (count > 0) {
System.out.println("count= " + count--);
}
}
}
public static void main(String[] args) {
hello h1 = new hello();
new Thread(h1,"1号").start();
new Thread(h1,"2号").start();
new Thread(h1,"3号").start();
}
}
【运行结果】:
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
count= 5
count= 4
count= 3
count= 2
count= 1
大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享。
我们换为Runnable接口:
class MyThread implements Runnable{
private int ticket = 5; //5张票
public void run() {
for (int i=0; i<=20; i++) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);
}
}
}
}
public class lzwCode {
public static void main(String [] args) {
MyThread my = new MyThread();
new Thread(my, "1号窗口").start();
new Thread(my, "2号窗口").start();
new Thread(my, "3号窗口").start();
}
}
【运行结果】:
count= 5
count= 4
count= 3
count= 2
count= 1
线程的休眠:
/**
* @author Rollen-Holt 线程的休眠
* */
class hello implements Runnable {
public void run() {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + i);
}
}
public static void main(String[] args) {
hello he = new hello();
Thread demo = new Thread(he, "线程");
demo.start();
}
}
【运行结果】:(结果每隔2s输出一个)
线程0
线程1
线程2
线程的中断:
/**
* @author Rollen-Holt 线程的中断
* */
class hello implements Runnable {
public void run() {
System.out.println("执行run方法");
try {
Thread.sleep(10000);
System.out.println("线程完成休眠");
} catch (Exception e) {
System.out.println("休眠被打断");
return; //返回到程序的调用处
}
System.out.println("线程正常终止");
}
public static void main(String[] args) {
hello he = new hello();
Thread demo = new Thread(he, "线程");
demo.start();
try{
Thread.sleep(2000);
}catch (Exception e) {
e.printStackTrace();
}
demo.interrupt(); //2s后中断线程
}
}
【运行结果】:
执行run方法
休眠被打断
【使用线程同步解决问题】
采用同步的话,可以使用同步代码块和同步方法两种来完成。
【同步代码块】:
语法格式:
synchronized(同步对象){
//需要同步的代码
}
但是一般都把当前对象this作为同步对象。
比如对于上面的买票的问题,如下:
/**
* @author Rollen-Holt
* */
class hello implements Runnable {
public void run() {
for(int i=0;i<10;++i){
synchronized (this) {
if(count>0){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(count--);
}
}
}
}
public static void main(String[] args) {
hello he=new hello();
Thread h1=new Thread(he);
Thread h2=new Thread(he);
Thread h3=new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count=5;
}
【运行结果】:(每一秒输出一个结果)
5
4
3
2
1
【同步方法】
也可以采用同步方法。
语法格式为synchronized 方法返回类型方法名(参数列表){
// 其他代码
}
现在,我们采用同步方法解决上面的问题。
/**
* @author Rollen-Holt
* */
class hello implements Runnable {
public void run() {
for (int i = 0; i < 10; ++i) {
sale();
}
}
public synchronized void sale() {
if (count > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count--);
}
}
public static void main(String[] args) {
hello he = new hello();
Thread h1 = new Thread(he);
Thread h2 = new Thread(he);
Thread h3 = new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count = 5;
}
【运行结果】(每秒输出一个)
5
4
3
2
1
[(http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html 原文链接) 原文链接]