关于线程的八个常问面试题:
1、两个线程轮流打印数字,一直到100
public class MyPrintNumClass {
private int count = 0 ;
private final Object lock = new Object ( ) ;
public void printNumber ( ) throws InterruptedException {
new Thread ( new MyThread ( ) , "偶数" ) . start ( ) ;
Thread . sleep ( 1000 ) ;
new Thread ( new MyThread ( ) , "奇数" ) . start ( ) ;
}
class MyThread implements Runnable {
@Override
public void run ( ) {
while ( count <= 100 ) {
synchronized ( lock) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + ": " + count++ ) ;
lock. notifyAll ( ) ;
if ( count <= 100 ) {
try {
lock. wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
}
}
2、要求线程a执行完才开始线程b, 线程b执行完才开始c线程
public class MyPrintNumClass {
public void printThreadName ( ) throws InterruptedException {
PrintThread printThread1 = new PrintThread ( "线程1" ) ;
PrintThread printThread2 = new PrintThread ( "线程2" ) ;
PrintThread printThread3 = new PrintThread ( "线程3" ) ;
printThread1. start ( ) ;
printThread1. join ( ) ;
printThread2. start ( ) ;
printThread2. join ( ) ;
printThread3. start ( ) ;
printThread3. join ( ) ;
}
static class PrintThread extends Thread {
PrintThread ( String name) {
super ( name) ;
}
@Override
public void run ( ) {
System . out. println ( getName ( ) ) ;
}
}
}
3、两线程,一个打印数字从1到52,另一个打印字母从A到Z,输出:12A34B56C…5152Z
public class MyPrintNumClass {
private int count = 0 ;
private final Object lock = new Object ( ) ;
private boolean flag = true ;
public void printNumberAndLetter ( ) throws InterruptedException {
new Thread ( new PrintNumberAndLetterThread ( ) ) . start ( ) ;
Thread . sleep ( 1000 ) ;
new Thread ( new PrintNumberAndLetterThread ( ) ) . start ( ) ;
}
class PrintNumberAndLetterThread implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < 26 ; i++ ) {
synchronized ( lock) {
if ( flag) {
System . out. print ( ++ count) ;
System . out. print ( ++ count) ;
} else {
System . out. print ( ( char ) ( 65 + i) ) ;
}
flag = ! flag;
lock. notifyAll ( ) ;
if ( count < 52 ) {
try {
lock. wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
}
}
4、编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC…
public class MyPrintNumClass {
private int letterFlag = 1 ;
public void printLetter ( ) {
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
printA ( ) ;
}
} ) . start ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
printB ( ) ;
}
} ) . start ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
printC ( ) ;
}
} ) . start ( ) ;
}
public synchronized void printA ( ) {
for ( int i = 0 ; i < 5 ; i++ ) {
while ( letterFlag != 1 ) {
try {
wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
letterFlag = 2 ;
System . out. println ( "A" ) ;
notifyAll ( ) ;
}
}
public synchronized void printB ( ) {
for ( int i = 0 ; i < 5 ; i++ ) {
while ( letterFlag != 2 ) {
try {
wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
letterFlag = 3 ;
System . out. println ( "B" ) ;
notifyAll ( ) ;
}
}
public synchronized void printC ( ) {
for ( int i = 0 ; i < 5 ; i++ ) {
while ( letterFlag != 3 ) {
try {
wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
letterFlag = 1 ;
System . out. println ( "C" ) ;
notifyAll ( ) ;
}
}
}
5、编写10个线程,第一个线程从1加到10,第二个线程从11加20…第十个线程从91加到100,最后再把10个线程结果相加
public class MyPrintNumClass {
public int getSum ( ) {
int result = 0 ;
for ( int i = 0 ; i < 10 ; i++ ) {
GetSumThread thread = new GetSumThread ( i) ;
thread. start ( ) ;
try {
thread. join ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
result += thread. sum;
}
return result;
}
public static class GetSumThread extends Thread {
int threadNo = 0 ;
int sum = 0 ;
GetSumThread ( int threadNo) {
this . threadNo = threadNo;
}
@Override
public void run ( ) {
for ( int i = 1 ; i <= 10 ; i++ ) {
sum += i + threadNo * 10 ;
}
}
}
}
6、三个窗口同时卖票
public class MyPrintNumClass {
public void saleTicket ( ) {
Ticket ticket = new Ticket ( ) ;
SaleTicketWindowThread window1 = new SaleTicketWindowThread ( "窗口一" , ticket) ;
SaleTicketWindowThread window2 = new SaleTicketWindowThread ( "窗口二" , ticket) ;
SaleTicketWindowThread window3 = new SaleTicketWindowThread ( "窗口三" , ticket) ;
window1. start ( ) ;
window2. start ( ) ;
window3. start ( ) ;
}
class Ticket {
private int count = 1 ;
public void sale ( ) {
while ( true ) {
synchronized ( this ) {
if ( count > 50 ) {
System . out. println ( "票已经售完了!" ) ;
break ;
} else {
System . out. println ( Thread . currentThread ( ) . getName ( ) + "卖的第" + count++ + "张票" ) ;
}
try {
Thread . sleep ( 200 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
public static class SaleTicketWindowThread extends Thread {
private Ticket ticket;
SaleTicketWindowThread ( String threadName, Ticket ticket) {
super ( threadName) ;
this . ticket = ticket;
}
@Override
public void run ( ) {
ticket. sale ( ) ;
}
}
}
7、生产者与消费者
public class MyPrintNumClass {
private int count = 0 ;
private final Object lock = new Object ( ) ;
private final static int full = 10 ;
private Lock myLock;
private Condition notEmptyCondition;
private Condition notFullCondition;
{
myLock = new ReentrantLock ( ) ;
notEmptyCondition = myLock. newCondition ( ) ;
notFullCondition = myLock. newCondition ( ) ;
}
private BlockingQueue < Integer > queue = new ArrayBlockingQueue < > ( 10 ) ;
public void synchronizedProducerAndConsumer ( ) {
for ( int i = 1 ; i <= 5 ; i++ ) {
new Thread ( new Producer ( ) , "生产者-" + i) . start ( ) ;
new Thread ( new Consumer ( ) , "消费者-" + i) . start ( ) ;
}
}
class Producer implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < 10 ; i++ ) {
synchronized ( lock) {
while ( count == full) {
try {
lock. wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
System . out. println ( "生产者 " + Thread . currentThread ( ) . getName ( ) + " 总共有 " + ++ count + " 个资源" ) ;
lock. notifyAll ( ) ;
}
}
}
}
class Consumer implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < 10 ; i++ ) {
synchronized ( lock) {
while ( count == 0 ) {
try {
lock. wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
System . out. println ( "消费者 " + Thread . currentThread ( ) . getName ( ) + " 总共有 " + -- count + " 个资源" ) ;
lock. notifyAll ( ) ;
}
}
}
}
public void reentrantLockProducerAndConsumer ( ) {
for ( int i = 1 ; i <= 5 ; i++ ) {
new Thread ( new ReentrantLockProducer ( ) , "生产者-" + i) . start ( ) ;
new Thread ( new ReentrantLockConsumer ( ) , "消费者-" + i) . start ( ) ;
}
}
class ReentrantLockProducer implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < 10 ; i++ ) {
myLock. lock ( ) ;
try {
while ( count == full) {
try {
notFullCondition. await ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
System . out. println ( "生产者 " + Thread . currentThread ( ) . getName ( ) + " 总共有 " + ++ count + " 个资源" ) ;
notEmptyCondition. signal ( ) ;
} finally {
myLock. unlock ( ) ;
}
}
}
}
class ReentrantLockConsumer implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < 10 ; i++ ) {
myLock. lock ( ) ;
try {
while ( count == 0 ) {
try {
notEmptyCondition. await ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
System . out. println ( "消费者 " + Thread . currentThread ( ) . getName ( ) + " 总共有 " + -- count + " 个资源" ) ;
notFullCondition. signal ( ) ;
} finally {
myLock. unlock ( ) ;
}
}
}
}
public void blockingQueueProducerAndConsumer ( ) {
for ( int i = 1 ; i <= 5 ; i++ ) {
new Thread ( new BlockingQueueProducer ( ) , "生产者-" + i) . start ( ) ;
new Thread ( new BlockingQueueConsumer ( ) , "消费者-" + i) . start ( ) ;
}
}
class BlockingQueueProducer implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < 10 ; i++ ) {
try {
queue. put ( 1 ) ;
System . out. println ( "生产者 " + Thread . currentThread ( ) . getName ( ) + " 总共有 " + ++ count + " 个资源" ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
class BlockingQueueConsumer implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < 10 ; i++ ) {
try {
queue. take ( ) ;
System . out. println ( "消费者 " + Thread . currentThread ( ) . getName ( ) + " 总共有 " + -- count + " 个资源" ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
8、两个线程交替打印两个数组
public class MyPrintNumClass {
private int count = 0 ;
private final Object lock = new Object ( ) ;
private boolean flag = true ;
private int [ ] arr1 = new int [ ] { 1 , 3 , 5 , 7 , 9 } ;
private int [ ] arr2 = new int [ ] { 2 , 4 , 6 , 8 , 10 } ;
public void printTwoArr ( ) throws InterruptedException {
new Thread ( new PrintTwoArrThread ( ) ) . start ( ) ;
Thread . sleep ( 1000 ) ;
new Thread ( new PrintTwoArrThread ( ) ) . start ( ) ;
}
class PrintTwoArrThread implements Runnable {
@Override
public void run ( ) {
for ( int i = 0 ; i < arr1. length; i++ ) {
synchronized ( lock) {
if ( flag) {
System . out. println ( arr1[ i] ) ;
} else {
System . out. println ( arr2[ i] ) ;
}
count++ ;
flag = ! flag;
lock. notifyAll ( ) ;
if ( count < 2 * arr1. length - 1 ) {
try {
lock. wait ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
}
}
测试类
public class MyClass {
public static void main ( String [ ] args) throws InterruptedException {
MyPrintNumClass myPrintNumClass = new MyPrintNumClass ( ) ;
myPrintNumClass. printTwoArr ( ) ;
}
}