先上一个实例:两个人各自有3000块钱,要分别存入同一个账户,但是每个人每次只能存入1000块,要求每次存完钱后打印账户余额。
package thread.first;
//使用继承的方式实现多线程
class People extends Thread{
//两个属性必须设置为静态的,让不同的对象共用
private static int money;
private static Object object=new Object();
public void run(){
show();
}
public void show(){
synchronized (object) {//同步代码块,不同的对象共用一把锁
for(int i=3;i>0;i--){
money+=1000;
System.out.println(Thread.currentThread().getName()+":"+money);
}
}
}
}
public class TestCount {
public static void main(String[] args) {
People man1=new People();
People man2=new People();
man1.start();
man2.start();
}
}
/* 输出结果:
* Thread-0:1000
* Thread-0:2000
* Thread-0:3000
* Thread-1:4000
* Thread-1:5000
* Thread-1:6000
*/
使用继承的方式有很多缺点,具体对比实现的方式,上代码:
package thread.first;
//实现的方式实现多线程
class Man implements Runnable{
private int money=0;//不需要定义为static,多线程共用一个对象
public synchronized void run(){//同步方法,因为多线程共用一个对象,所以锁为当前对象
for(int i=3;i>0;i--){
money+=1000;
System.out.println(Thread.currentThread().getName()+":"+money);
}
}
}
public class TestCount {
public static void main(String[] args) {
Man people=new Man();
//只需要一个对象
Thread t1=new Thread(people);
Thread t2=new Thread(people);
t1.start();
t2.start();
}
}
/*
*/
第三种实现方式是实现Callable接口,个人理解这种方式最大的特别之处是有返回值。
package com.thread.demo;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class TestCallableThread {
// public static void main(String[] args) throws InterruptedException, ExecutionException {
// ThreadDemo threadDemo = new ThreadDemo();
// FutureTask<Integer> result = new FutureTask<>(threadDemo);
// new Thread(result).start();
// System.out.println(result.get().toString());
// }
public static void main(String[] args) {
Woman woman = new Woman();
FutureTask<Object> futureTask1 = new FutureTask<>(woman);
FutureTask<Object> futureTask2 = new FutureTask<>(woman);
new Thread(futureTask1).start();
new Thread(futureTask2).start();
}
}
class Woman implements Callable<Object>{
private int money=0;//不需要定义为static,多线程共用一个对象
@Override
public synchronized Object call() throws Exception {
for(int i=3;i>0;i--){
money+=1000;
System.out.println(Thread.currentThread().getName()+":"+money);
}
return null;
}
}
class ThreadDemo implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("ThreadDemo Call");
return 23;
}
}
线程通信,最经典的例子就是生产者消费者模型,上代码:
package thread.first;
class Clerk{//店员类,用来协调生产者和消费者
int productNum;//商品数目,假设店里最多放入5个商品
public synchronized void add(){
if(productNum<5){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
productNum++;
System.out.println("生产者生产了第"+productNum+"个商品");
notifyAll();
}else{//如果等于5了,让生产者等待
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public synchronized void reduce(){
if(productNum>0){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费者消费了第"+productNum+"个商品");
productNum--;
notifyAll();
}else{//没有商品了,让消费者等待
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Producer implements Runnable{
Clerk clerk;
public Producer(Clerk clerk){
this.clerk=clerk;
}
public void run(){
//System.out.println("生产者生产产品");
while(true){
clerk.add();
}
}
}
class Customer implements Runnable{
Clerk clerk;
public Customer(Clerk clerk){
this.clerk=clerk;
}
public void run(){
//System.out.println("消费者消费产品");
while(true){
clerk.reduce();
}
}
}
public class TestProCustomer {
public static void main(String[] args) {
Clerk clerk=new Clerk();
Producer producer1=new Producer(clerk);
Producer producer2=new Producer(clerk);
Customer customer1=new Customer(clerk);
Customer customer2=new Customer(clerk);
Thread t1=new Thread(producer1);
Thread t2=new Thread(producer2);
Thread t3=new Thread(customer1);
Thread t4=new Thread(customer2);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*生产者生产了第1个商品
生产者生产了第2个商品
消费者消费了第2个商品
消费者消费了第1个商品
生产者生产了第1个商品
生产者生产了第2个商品
生产者生产了第3个商品
生产者生产了第4个商品
生产者生产了第5个商品
消费者消费了第5个商品
消费者消费了第4个商品
*/