java编程笔记21 线程
1,两种方法来创建线程:
1)继承Thread类实现run方法:
public class Hello1 extends Thread{
String name;
public Hello1(String n)
{
name = n;
}
public void run()
{
for (int i=1; i<=10; i++)
{
System.out.println(name+" Hello "+i);
}
}
}
2)实现Runnable接口,实现run方法:
public class Hello2 implements Runnable{
String name;
public Hello2(String n)
{
name = n;
}
public void run()
{
for (int i=1; i<=10; i++)
System.out.println(name+" Hello "+i);
}
}
推荐第二种方法;
2,产生Thread对象和启动线程
public class ThreadsExample1{
public static void main(String argv[])
{
Hello1 h1 = new Hello1("Thread1");
Hello2 h2 = new Hello2("Thread2");
Thread t1 = new Thread(h1);
Thread t2 = new Thread(h2);
t1.start();
t2.start();
}
}
3,停止线程运行
下面的run方法可以让线程一直运行:
public class Hello3 implements Runnable{
String name;
public Hello3(String n)
{
name = n;
}
public void run()
{
int i=0;
while(true)//这样来写run方法
{
i++;
System.out.println(name+" Hello "+i);
}
}
}
加一个循环条件来达到停止现成的效果:
public class Hello4 implements Runnable{
String name;
Boolean isStop;
public Hello4(String n)
{
name = n;
isStop = false;
}
public void run()
{
int i=0;
while(!isStop)
{
i++;
System.out.println(name+" Hello "+i);
}
}
public void stop()//控制条件
{
isStop = true;
}
}
当一个线程对象进入死亡状态后,就没有任何方法可以回到其他状态。
4,暂停线程运行
sleep方法:
yield方法
join方法,
来看join的一个例子:
MotherThread:
package ch22;public class MotherThread implements Runnable
{
public void run()
{
System.out.println("妈妈准备煮饭");
System.out.println("妈妈发现米酒用完了");
System.out.println("妈妈叫儿子去买米酒");
Thread son = new Thread(new SonThread());
son.start();
System.out.println("妈妈等待儿子把米酒买回来");
try {
son.join();
}
catch (InterruptedException ie)
{
System.err.println("发生异常!");
System.err.println("妈妈中断煮饭");
System.exit(1);
}
System.out.println("妈妈开始煮饭");
System.out.println("妈妈煮好饭了");
}
}
SonThread:
package ch22;public class SonThread implements Runnable
{
public void run()
{
System.out.println("儿子出门去买米酒");
System.out.println("儿子买东西来回需5分钟");
try {
for (int i=1; i<=5; i++)
{
Thread.sleep(1000);
System.out.print(i+"分钟 ");
}
}
catch (InterruptedException ie)
{
System.err.println("儿子发生意外");
}
System.out.println("\n儿子买米酒回来了");
}
}
Cooking:
package ch22;public class Cooking
{
public static void main(String argv[])
{
Thread mother = new Thread(new MotherThread());
mother.start();
}
}
运行结果:
5,数据同步处理
现在我们有这样一个线程:
package ch22;public class ShareData implements Runnable
{
int i;
public void run()
{
while (i<10)
{
i++;
for(int j=0; j<10000000; j++);
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
现在我们来产生两个ShareData对象,并给两个Thread运行:
package ch22;public class ThreadsExample2
{
public static void main(String argv[])
{
ShareData s1 = new ShareData();
ShareData s2 = new ShareData();
Thread t1 = new Thread(s1);
Thread t2 = new Thread(s2);
t1.start();
t2.start();
}
}
其结果如图:
可以看到,两个Thread对象在交互运行,Thread 0和Thread 1分别从0按顺序到10.
这是因为两个Thread共用了程序代码但是没有共用数据,下面我们来看程序代码和数据都共用的效果:
package ch22;public class ThreadsExample3
{
public static void main(String argv[])
{
ShareData s = new ShareData();
Thread t1 = new Thread(s);//两个小成共用一个对象ShareData
Thread t2 = new Thread(s);
t1.start();
t2.start();
}
}
结果并不是你所想象的从0到10,而是:
这是为什么呢????
这是因为线程被分割运行了,具体分析略。
6,synchronized实现线程同步
synchronized(要取得锁的对象)
{
要锁定的代码
}
package ch22;public class SyncShareData implements Runnable
{
int i;
public void run()
{
while (i<10)
{
/*锁的对象是SyncShareData自己,也就是说这个对象对应的线程要进行同步机制*/
synchronized(this)
{
i++;
for(int j=0; j<10000000; j++);
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
package ch22;public class ThreadsExample4
{
public static void main(String argv[])
{
SyncShareData s = new SyncShareData();
/*t1和t2都是操作同一个SyncShareData对象的线程,
* 要进行同步机制,因为SyncShareData实现了锁机制*/
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start();
t2.start();
}
}
实现了两个线程对同一个对象操作的同步
7,等待wait与通报notify
生产者和消费者的例子:
package ch22;public class Storage
{
private int count;//当前库存值
private int size;//最大库存量
public Storage(int s)
{
size = s;
}
//类里的方法实现了锁,则调用这个方法必须取得这个类的对象的锁
public synchronized void addData(String n)
{
while (count == size)//注意为什么要用while循环而不是if
{
try {
this.wait();//进入等待状态
}
catch (InterruptedException e) { }
}
this.notify();//通知消费者可以消费了
count++;
System.out.println(n+" make data count: "+count);
}
public synchronized void delData(String n)
{
while (count == 0)
{
try {
this.wait();
}
catch (InterruptedException e) { }
}
this.notify();
System.out.println(n+" use data count: "+count);
count--;
}
}
package ch22;public class Producer extends Thread
{
private String name;
private Storage s;
public Producer(String n, Storage s)
{
name = n;
this.s = s;
}
public void run()
{
while (true)
{
s.addData(name);
try {
sleep((int)Math.random()*3000);
}
catch (InterruptedException e) { }
}
}
}
package ch22;public class Consumer extends Thread
{
private String name;
private Storage s;
public Consumer(String n, Storage s)
{
name = n;
this.s = s;
}
public void run()
{
while (true)
{
s.delData(name);
try {
sleep((int)Math.random()*3000);
}
catch (InterruptedException e) { }
}
}
}
package ch22;public class ThreadsExample5
{
public static void main(String argv[])
{
Storage s = new Storage(3);
Producer p1 = new Producer("Producer1", s);
Producer p2 = new Producer("Producer2", s);
Consumer c1 = new Consumer("Consumer1", s);
p1.start();
p2.start();
c1.start();
}
}
.........
Producer1 make data count: 3
Consumer1 use data count: 3
Consumer1 use data count: 2
Producer1 make data count: 2
Consumer1 use data count: 2
Producer1 make data count: 2
.........
以上是 java编程笔记21 线程 的全部内容, 来源链接: utcz.com/z/390467.html