案例1
設計一個線程操作類,要求可以產生三個線程對象,並可以設置三個線程的休眠時間
分析:
1.使用Thread類實現
class MyThread extends Thread
{
//封裝屬性
private String name ; //定義該線程的名稱
private int time; //定義休眠時間
//構造方法
public MyThread(String name , int time)
{
super(name);
this.time = time;
}
//覆寫run方法
public void run()
{
System.out.println(Thread.currentThread().getName() + "休眠開始");
try
{
Thread.currentThread().sleep(this.time);
}
catch (InterruptedException e)
{
System.out.println(Thread.currentThread().getName() +"休眠中斷");
}
System.out.println(Thread.currentThread().getName() + "休眠結束" + "持續:" + this.time + "ms");
}
}
public class TestThread16
{
public static void main(String[] args)
{
MyThread mt1 = new MyThread("線程A",1000);
mt1.start();
MyThread mt2 = new MyThread("線程B",2000);
mt2.start();
MyThread mt3 = new MyThread("線程C",3000);
mt3.start();
}
}
1.使用Runnable接口實現
class MyThread implements Runnable
{
//封裝屬性
private String name ;
private int time ;
//構造方法
public MyThread(String name , int time)
{
this.name = name ;
this.time = time ;
}
public String getName()
{
return this.name ;
}
//覆寫run方法
public void run()
{
System.out.println(this.name + "休眠開始");
try
{
Thread.currentThread().sleep(this.time);
}
catch (InterruptedException e)
{
System.out.println(this.name +"休眠中斷");
}
System.out.println(this.name + "休眠結束" + "持續:" + this.time + "ms");
}
}
public class TestThread17
{
public static void main(String[] args)
{
MyThread mt1 = new MyThread("線程A",1000);
new Thread(mt1).start() ;
MyThread mt2 = new MyThread("線程B",2000);
new Thread(mt2).start() ;
MyThread mt3 = new MyThread("線程C",3000);
new Thread(mt3).start() ;
}
}
同步
問題的引出:把各個售票點理解爲線程,那麼各個線程需要共享資源。如果引入延時,系統可能存在負數的問題。
class Sale implements Runnable
{
private int ticket = 5;
public void run()
{
for (int i =0;i<50 ; ++i )
{
if (ticket>0)
{
System.out.println("買票成功,還剩下票數 ticcket=" + ticket--);
}
}
}
}
public class TestChronized1
{
public static void main(String[] args)
{
Sale s = new Sale();
Thread th1 = new Thread(s);
Thread th2 = new Thread(s);
Thread th3 = new Thread(s);
th1.start();
th2.start();
th3.start();
}
}
下面引入延時
class Sale implements Runnable
{
private int ticket = 5;
public void run()
{
for (int i =0;i<50 ; ++i )
{
if (ticket>0)
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("買票成功,還剩下票數 ticcket=" + ticket--);
}
}
}
}
public class TestChronized1
{
public static void main(String[] args)
{
Sale s = new Sale();
Thread th1 = new Thread(s);
Thread th2 = new Thread(s);
Thread th3 = new Thread(s);
th1.start();
th2.start();
th3.start();
}
}
結果
要想解決數據共享問題——使用同步代碼塊或同法方法。
同步代碼塊
class Sale implements Runnable
{
private int ticket = 5;
public void run()
{
for (int i =0;i<50 ; ++i )
{
synchronized (this)
{
if (ticket>0)
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("買票成功,還剩下票數 ticcket=" + ticket--);
}
}
}
}
}
public class TestChronized2
{
public static void main(String[] args)
{
Sale s = new Sale();
Thread th1 = new Thread(s);
Thread th2 = new Thread(s);
Thread th3 = new Thread(s);
th1.start();
th2.start();
th3.start();
}
}
同步代碼塊:
Synchronized (同步對象){}
其中同步對象一般使用this代替
同步方法
class Sale implements Runnable
{
private int ticket = 5;
public void run()
{
for (int i =0;i<50 ; ++i )
{
saleTicket();
}
}
public synchronized void saleTicket()
{
if (ticket>0)
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("買票成功,還剩下票數 ticcket=" + ticket--);
}
}
}
public class TestChronized3
{
public static void main(String[] args)
{
Sale s = new Sale();
Thread th1 = new Thread(s);
Thread th2 = new Thread(s);
Thread th3 = new Thread(s);
th1.start();
th2.start();
th3.start();
}
}
結果完全相同
Synchronized 方法返回值 方法() {}
死鎖
不同的線程在互相等待
只要數據共享就需要同步
過分同步就會產生死鎖