java基础复习总结5

本文深入探讨Java中线程的基本概念、实现方式及应用实例,包括如何创建线程、线程同步、死锁避免、wait与notify方法的使用等关键知识点。详细解释了成员变量与局部变量的区别,以及synchronized关键字的使用方法,帮助开发者理解和掌握Java多线程编程的核心技术。

      Java 中如果我们自己没有产生线程,那么系统就会给我们产生一个线程(主线程,main方法就在主线程上运行) ,我们的程序都是由线程来执行的。
      进程:执行中的程序(程序是静态的概念,进程是动态的概念)。
      线程的实现有两种方式,第一种方式是继承 Thread类,然后重写run方法;第二种是实现Runnable 接口,然后实现其 run方法。 将我们希望线程执行的代码放到 run方法中,然后通过 start 方法来启动线程,start方法首先为线程的执行准备好系统资源,然后再去调用 run 方法。当某个类继承了Thread类之后,该类就叫做一个线程类。

当使用第二种Runnable接口定义 也可以 new thread(new Runnable(){})

public class ThreadTest2
{
	public static void main(String[] args)
	{
//		Thread t1 = new Thread(new Runnable()
//		{
//			@Override
//			public void run()
//			{
//				for(int i = 0; i < 100; i++)
//				{
//					System.out.println("hello :" + i);
//				}
//			}
//		});
//		
//		t1.start();
		
		Thread t1 = new Thread(new MyThread());
		
		t1.start();
		
		Thread t2 = new Thread(new MyThread2());
		
		t2.start();
	
		
	}
}

class MyThread implements Runnable
{
	@Override
	public void run()
	{
		for(int i = 0; i < 100; i++)
		{
			System.out.println("hello :" + i);
		}
	}
}

     关于成员变量与局部变量:如果一个变量是成员变量,那么多个线程对同一个对象的成员变量进行操作时,他们对该成员变量是彼此影响的(也就是说一个线程对成员变量的改变会影响到另一个线程) 。 如果一个变量是局部变量,那么每个线程都会有一个该局部变量的拷贝,一个线程对该局部变量的改变不会影响到其他的线程。

public class ThreadTest3
{
	public static void main(String[] args)
	{
		Runnable r = new HelloThread();
		
		Thread t1 = new Thread(r);
		
		//r = new HelloThread();
		
		Thread t2 = new Thread(r);
		
		t1.start();
		t2.start();
	}
}

class HelloThread implements Runnable
{
	int i;
	
	@Override
	public void run()
	{
		int i = 0;
		
		while(true)
		{
			System.out.println("number: " + this.i++);
			
			try
			{
				Thread.sleep((long)(Math.random() * 1000));
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			
			if(50 == this.i)
			{
				break;
			}
		}
	}
}

    synchronized关键字:当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。
    Java 中的每个对象都有一个锁(lock)或者叫做监视器(monitor) ,当访问某个对象的 synchronized 方法时,表示将该对象上锁,此时其他任何线程都无法再去访问该 synchronized方法了,直到之前的那个线程执行方法完毕后(或者是抛出了异常) ,那么将该对象的锁释放掉,其他线程才有可能再去访问该 synchronized方法。 如果一个对象有多个 synchronized 方法,某一时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕前,其他线程是无法访问该对象的任何 synchronized方法的。

public class ThreadTest5
{
	public static void main(String[] args)
	{
		Example2 e = new Example2();

		TheThread3 t1 = new TheThread3(e);
		
		e = new Example2();
		
		TheThread4 t2 = new TheThread4(e);

		t1.start();
		t2.start();
	}
}

class Example2
{
	private Object object = new Object();

	public void execute()
	{
		synchronized (this)
		{
			for (int i = 0; i < 20; i++)
			{
				try
				{
					Thread.sleep((long) (Math.random() * 1000));
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}

				System.out.println("hello: " + i);
			}
		}

	}

	public void execute2()
	{
		synchronized(this)
		{
			for (int i = 0; i < 20; i++)
			{
				try
				{
					Thread.sleep((long) (Math.random() * 1000));
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}

				System.out.println("world: " + i);
			}
		}
		
		
	}
}

class TheThread3 extends Thread
{
	private Example2 example;

	public TheThread3(Example2 example)
	{
		this.example = example;
	}

	@Override
	public void run()
	{
		this.example.execute();
	}
}

class TheThread4 extends Thread
{
	private Example2 example;

	public TheThread4(Example2 example)
	{
		this.example = example;
	}

	@Override
	public void run()
	{
		this.example.execute2();
	}
}

     如果某个 synchronized 方法是 static 的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在的对象所对应的 Class对象,因为 Java 中无论一个类有多少个对象,这些对象会对应唯一一个 Class 对象,因此当线程分别访问同一个类的两个对象的两个 static,synchronized 方法时,他们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始执行。

   synchronized块,写法:
synchronized(object)
{
 
}
    表示线程在执行的时候会对 object 对象上锁。
synchronized 方法是一种粗粒度的并发控制,某一时刻,只能有一个线程执行该
synchronized方法;synchronized块则是一种细粒度的并发控制,只会将块中的代码同
步,位于方法内、synchronized块之外的代码是可以被多个线程同时访问到的。

死锁(deadlock)

wait 与 notify 方法都是定义在 Object 类中,而且是 final 的,因此会被所有的 Java
类所继承并且无法重写。这两个方法要求在调用时线程应该已经获得了对象的锁,
因此对这两个方法的调用需要放在 synchronized 方法或块当中。当线程执行了 wait
方法时,它会释放掉对象的锁。
另一个会导致线程暂停的方法就是 Thread 类的 sleep 方法,它会导致线程睡眠指定
的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。

被synchronized 一般都是private

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值