[ Java学习 ] 线程 书上代码

//这次吸取了之前做实验的教训,在做实验之前,先把书上的有关代码都敲了一次...虽然好像没什么用,因为实验还是做得很艰难...不过这次实验本来就难,所以也许其实是有用的,只是我没感受到罢了...




//TaskThreadDemo.java
public class TaskThreadDemo 
{
	public static void main(String[] args)
	{
		//Create tasks
		Runnable printA = new PrintChar('a', 100);
		Runnable printB = new PrintChar('b', 100);
		Runnable print100 = new PrintNum(100);
		
		//Create threads
		Thread thread1 = new Thread(printA);
		Thread thread2 = new Thread(printB);
		Thread thread3 = new Thread(print100);
		
		//Run threads
		thread1.start();
		thread2.start();
		thread3.start();
	}

}
class PrintChar implements Runnable
{
	//The task for printing a character a specified number of times
	private char charToPrint; //The character to print
	private int times;// The number of times to repeat
	
	//Construct a task with specified character and number of times to print the character
	public PrintChar(char c, int t)
	{
		charToPrint = c;
		times = t;
	}
	
	//Override the run() method to tell the system what task to perform
	public void run()
	{
		for (int i = 0; i < times; i++)
			System.out.print(charToPrint);
		System.out.println();
	}
}

//The task for printing numbers from 1 to n for a giving n
class PrintNum implements Runnable
{
	private int lastNum;
	
	//Construct a task for printing 1, 2, 3, ..., n
	public PrintNum(int n)
	{
		lastNum = n;
	}
	
	//Tell the thread how to run
	public void run()
	{
		for (int i = 1; i <= lastNum; i++)
			System.out.print(" " + i);
		System.out.println();
	}
}

/*重要注意事项:
 * 任务中的 run() 方法指明如何完成这个任务。Java虚拟机会自动调用该方法,无需特意调用它。
 * 直接调用 run() 只是在同一个线程中执行该方法,而没有新线程被启动
 */

import javax.swing.*;
public class FlashingText extends JApplet implements Runnable
{
	private JLabel j1b1Text = new JLabel("Welcome", JLabel.CENTER);
	
	public FlashingText()
	{
		add(j1b1Text);
		new Thread(this).start();
	}
	
	// Set the text on/off every 200 milliseconds
	public void run()
	{
		try
		{
			while (true)
			{
				if (j1b1Text.getText() == null)
					j1b1Text.setText("Welcome");
				else
					j1b1Text.setName(null);
				
				Thread.sleep(200);
			}
		}
		catch(InterruptedException e) {}
	}
}

//改写 TaskThreadDemo.java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorDemo 
{
	public static void main(String[] args)
	{
		//Create a fixed thread pool with maximum three threads
		ExecutorService executor = Executors.newFixedThreadPool(3);
		
		//Submit runnable tasks to the executor
		executor.execute(new PrintChar('a', 100));
		executor.execute(new PrintChar('b', 100));
		executor.execute(new PrintNum(100));
		
		//Shut down the executor
		executor.shutdown();
	}
}
class PrintChar implements Runnable
{
	//The task for printing a character a specified number of times
	private char charToPrint; //The character to print
	private int times;// The number of times to repeat
	
	//Construct a task with specified character and number of times to print the character
	public PrintChar(char c, int t)
	{
		charToPrint = c;
		times = t;
	}
	
	//Override the run() method to tell the system what task to perform
	public void run()
	{
		for (int i = 0; i < times; i++)
			System.out.print(charToPrint);
		System.out.println();
	}
}

//The task for printing numbers from 1 to n for a giving n
class PrintNum implements Runnable
{
	private int lastNum;
	
	//Construct a task for printing 1, 2, 3, ..., n
	public PrintNum(int n)
	{
		lastNum = n;
	}
	
	//Tell the thread how to run
	public void run()
	{
		for (int i = 1; i <= lastNum; i++)
			System.out.print(" " + i);
		System.out.println();
	}
}
//如果需要为一个任务创建一个线程,就使用Thread类。如果需要为多个任务创建线程,最好使用线程池

//此例用于引入“竞争状态”和“线程安全的”这两个概念
//当所有线程同时访问同一个数据时,就会出现数据破坏的问题

import java.util.concurrent.*;
public class AccountWithoutSync 
{
	private static Account account = new Account();
	public static void main(String[] args)
	{
		ExecutorService executor = Executors.newCachedThreadPool();
		// Create and launch 100 threads
		for (int i = 0; i < 100; i++)
			executor.execute(new AddAPennyTask());
		executor.shutdown();
		
		while (!executor.isTerminated()) {}
		System.out.println("What is balance? " + account.getBalance());
	}
	
	// A thread for adding a penny to account
	private static class AddAPennyTask implements Runnable
	{
		public void run()
		{
			account.deposit(1);
		}
	}
	
	// An inner class for account
	private static class Account
	{
		private int balance = 0;
		public int getBalance()
		{
			return balance;
		}
		public void deposit(int amount)
		{
			int newBalance = balance + amount;
			// This delay is deliberately added to magnify the data-corruption problem and make it easy to see.
			try
			{
				Thread.sleep(5);
			}
			catch(InterruptedException e) {}
			balance = newBalance;
		}
	}
}

//使用显示锁来修改 AccountWithoutSync.java

import java.util.concurrent.*;
import java.util.concurrent.locks.*;
public class AccountWithSyncUsingLock 
{
	private static Account account = new Account();
	public static void main(String[] args)
	{
		ExecutorService executor = Executors.newCachedThreadPool();
		// Create and launch 100 threads
		for (int i = 0; i < 100; i++)
			executor.execute(new AddAPennyTask());
		executor.shutdown();
		
		// Wait until all tasks are finished
		while (!executor.isTerminated()) {}
		System.out.println("What is balance? " + account.getBalance());
	}
	
	// A thread for adding a penny to account
	private static class AddAPennyTask implements Runnable
	{
		public void run()
		{
			account.deposit(1);
		}
	}
	
	// An inner class for account
	private static class Account
	{
		private static Lock lock = new ReentrantLock(); // Create a lock
		private int balance = 0;
		public int getBalance()
		{
			return balance;
		}
		public void deposit(int amount)
		{
			lock.lock(); // Acquire the lock
			try
			{
				int newBalance = balance + amount;
				
				// This delay is deliberately added to magnify the data-corruption problem and make it easy to see.
				Thread.sleep(5);
				
				balance = newBalance;
			}
			catch(InterruptedException e) {}
			finally
			{
				lock.unlock(); // Release the lock
			}		
		}
	}
}
// 对 lock() 的调用之后紧随一个  try-catch 块并且在 finally 子句中释放这个锁是比较好的写法,可以确保锁被释放
// 通常,使用 synchronized 方法或语句必使用相互排斥的显示锁简单些。然而,使用显示锁对同步具有状态的线程更加直观和灵活

import java.util.concurrent.*;
import java.util.concurrent.locks.*;
public class ThreadCooperation 
{
	private static Account account = new Account();
	public static void main(String[] args)
	{
		// Create a thread pool with two threads
		ExecutorService executor = Executors.newFixedThreadPool(2);
		executor.execute(new DepositTask());
		executor.execute(new WithdrawTask());
		executor.shutdown();
		
		System.out.println("Thread 1\t\tThread 2\t\tBalance");
	}
	public static class DepositTask implements Runnable
	{
		public void run()
		{
			try
			{ // Purposely delay it to let the withdraw method proceed
				while(true)
				{
					account.deposit((int)(Math.random() * 10) + 1);
					Thread.sleep(1000);
				}
			}
			catch(InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
	
	// A task for subtracting an amount from the account
	public static class WithdrawTask implements Runnable
	{
		public void run()
		{
			
		}
	}
	// An inner class for account
	private static class Account
	{
		private static Lock lock = new ReentrantLock(); // Create a lock
		
		// Create a condition
		private static Condition newDeposit = lock.newCondition();
		
		private int balance = 0;
		
		public int getBalance()
		{
			return balance;
		}
		
		public void withdraw(int amount)
		{
			lock.lock(); // Acquire the lock
			try
			{
				while (balance < amount)
				{//注意:此处的 while 语句如果换为 if语句,提款任务可能永久等待。如果使用循环语句,则提款任务可以有重新检验条件的机会。因此,应该在循环语句中测试条件
					System.out.println("\t\t\tWait for a deposit");
					newDeposit.await();
				}
				
				balance -= amount;
				System.out.println("\t\t\tWithdraw " + amount + "\t\t" + getBalance());
			}
			catch (InterruptedException e) {}
			finally
			{
				lock.unlock(); // Release the lock
			}
		}
		
		public void deposit(int amount)
		{
			lock.lock(); // Acquire the lock
			try
			{
				balance += amount;
				System.out.println("Deposit " + amount + "\t\t\t\t\t" + getBalance());
				
				// Signal thread waiting on the condition
				newDeposit.signalAll();
			}
			finally
			{
				lock.unlock();
			}
		}
	}		
}
// 一旦线程调用条件上的 await(),线程就进入等待状态,等待回复的信号。如果忘记对状态调用 signal() 或 signalAll(),那么线程就永远等待下去。
//条件由Lock对象创建。为了调用任意方法(例如,await()、signal()和signalAll()),必须首先拥有锁。如果没有获取锁就调用这些方法,会抛出IllegalMonitorStateException异常

//生产者 / 消费者问题的有关代码

import java.util.concurrent.*;
import java.util.concurrent.locks.*;
public class ConsumerProducer 
{
	private static Buffer buffer =  new Buffer();
	public static void main(String[] args)
	{
		// Create a thread pool with two threads
		ExecutorService executor = Executors.newFixedThreadPool(2);
		executor.execute(new ProducerTask());
		executor.execute(new ConsumerTask());
		executor.shutdown();
	}
	
	// A task for adding an int to the buffer
	private static class ProducerTask implements Runnable
	{
		public void run()
		{
			try
			{
				int i = 1;
				while (true)
				{
					System.out.println("Producer writes " + i);
					buffer.write(i++); // Add value to the buffer
					// Put the thread to sleep
					Thread.sleep((int)(Math.random()) * 10000);
				}
			}
			catch(InterruptedException e)
			{e.printStackTrace();}
		}
	}
	
	private static class ConsumerTask implements Runnable
	{
		public void run()
		{
			try
			{
				while (true)
				{
					System.out.println("\t\t\tConsumer reads " + buffer.read());
					// Put the thread into sleep
					Thread.sleep((int)(Math.random() * 10000));
				}
			}
			catch(InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
	// An inner class for buffer
	private static class Buffer
	{
		private static final int CAPACITY = 1; // buffer size
		private java.util.LinkedList<Integer> queue = new java.util.LinkedList<Integer>();
		
		// Create a new lock
		private static Lock lock = new ReentrantLock();
		
		// Create two conditions
		private static Condition notEmpty = lock.newCondition();
		private static Condition notFull = lock.newCondition();
		
		public void write(int value)
		{
			lock.lock(); // Acquire the lock
			try
			{
				while (queue.size() == CAPACITY)
				{
					System.out.println("Wait for notFull condition");
					notFull.await();
				}
				queue.offer(value);
				notEmpty.signal(); // Signal notEmpty Condition
			}
			catch(InterruptedException e)
			{e.printStackTrace();}
			finally
			{
				lock.unlock();
			}
		}
		
		public int read()
		{
			int value = 0;
			lock.lock(); // Acquire the lock
			try
			{
				while (queue.isEmpty())
				{
					System.out.println("\t\t\tWait for notEmpty condition");
					notEmpty.await();
				}
				
				value = queue.remove();
				notFull.signal(); // Signal notFull condition
			}
			catch(InterruptedException e)
			{e.printStackTrace();}
			finally
			{
				lock.unlock(); // Release the lock
				return value;
			}
		}
	}
}

//使用锁和条件同步生产者和消费者线程。在这个程序中,同步已经在 ArrayBlockingQueue 中实现,所以无需进行手动编码
import java.util.concurrent.*;
public class ConsumerProducerUsingBlockingQueue 
{
	private static ArrayBlockingQueue<Integer> buffer = new ArrayBlockingQueue<Integer>(2);
	public static void main(String[] args)
	{
		// Create a thread pool with two threads
		ExecutorService executor = Executors.newFixedThreadPool(2);
		executor.execute(new ProducerTask());
		executor.execute(new ConsumerTask());
		executor.shutdown();
	}
	
	// A task for adding an int to the buffer
	private static class ProducerTask implements Runnable
	{
		public void run()
		{
			try
			{
				int i = 1;
				while (true)
				{
					System.out.println("Producer writes " + i);
					buffer.put(i++); // Add value to the buffer
					// Put the thread to sleep
					Thread.sleep((int)(Math.random()) * 10000);
				}
			}
			catch(InterruptedException e)
			{e.printStackTrace();}
		}
	}
	
	private static class ConsumerTask implements Runnable
	{
		public void run()
		{
			try
			{
				while (true)
				{
					System.out.println("\t\t\tConsumer reads " + buffer.take());
					// Put the thread into sleep
					Thread.sleep((int)(Math.random() * 10000));
				}
			}
			catch(InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}
}
//改写 AccountWithSyncUsingLock.java 中的 Account 内部类

// An inner class for account
	private static class Account
	{
		// Create a semaphore
		private static Semaphore semaphore = new Semophore(1);
		private int balance = 0;
		public int getBalance()
		{
			return balance;
		}
		public void deposit(int amount)
		{
			try
			{
				semaphore.acquire();
				int newBalance = balance + amount;
				
				// This delay is deliberately added to magnify the data-corruption problem and make it easy to see.
				Thread.sleep(5);
				
				balance = newBalance;
			}
			catch(InterruptedException e) {}
			finally
			{
				semaphore.release();
			}
		}
	}
	// 将release()方法放到finally子句中,可以确保即使发生异常也能最终释放该许可


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值