synchronized关键字
每个Runnable接口对象或Thread子类对象都可通过关键字synchronized的修饰,保证自身在任意时刻只能由1个线程来访问,即给自己套上互斥锁。程序执行到synchronized语句时,会先执行synchronized括号中的内容,要保证多个线程访问的1个或多个对象执行的结果一致。
实现互斥锁步骤
- 分析上锁代码
- 选择同步代码快或同步方法
- 合理选择synchronized括号里的参数,保证多个线程的锁对象为同一个
错误例程
public class thread
{
public static void main(String[] args)
{
ticket t1=new ticket();
ticket t2=new ticket();
ticket t3=new ticket();
t1.start();t2.start();t3.start();
}
}
class ticket extends Thread {
private static int num=100;
public void m() {
synchronized (this) {
System.out.println(--num);
}
}
public void run() {
while(num>=0){
m();
}
}
}
错误原因
t1、t2、t3三个线程未对同一个对象进行操作。3个ticket类对象各自都有一把互斥锁,相当于未进行同步处理。把synchronized括号里的参数改为ticket.class即可纠正错误。
正确例程
public class thread
{
public static void main(String[] args)
{
Ticket t1=new Ticket(); //创建了1个Runnable接口对象
Thread x1=new Thread(t1);//创建了3个进程对象从而启动了3个线程,3个线程操作的对象都是括号中的接口对象t1
Thread x2=new Thread(t1);
Thread x3=new Thread(t1);
x1.start();x2.start();x3.start();
}
}
class Ticket implements Runnable
{
private static int num=100;
private static boolean loop=true;
private void sell()
{
synchronized (this)
{
if(num<=0)
{
loop=false;
}
else
{
try{
Thread.sleep(10);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖了1张票,还剩"+(--num)+"张票。");
}
}
}
public void run()
{
while(loop) {
sell();
}
}
}